zoukankan      html  css  js  c++  java
  • 设计模式

    模板方法模式(template method pattern) 详细解释


    本文地址: http://blog.csdn.net/caroline_wendy


    模板方法模式(template method pattern): 在一个方法中定义一个算法的骨架, 而将一些步骤延迟到子类中. 

    模板方法使得子类能够在不改变算法结构的情况下, 又一次定义算法中的某些步骤.


    模板方法能够进行挂钩(hook), 钩子(hook)是一种被声明在抽象类中的方法, 但仅仅有空的或者默认的实现.

    钩子的存在, 能够让子类有能力对算法的不同点进行挂钩.


    抽象类的框架:

    /**
     * @time 2014年6月18日
     */
    package template_method;
    
    /**
     * @author C.L.Wang
     *
     */
    public abstract class AbstractClass {
    	
    	final void templateMethod() {
    		primitiveOperation1();
    		primitiveOperation2();
    		concreteOperation();
    		hook();
    	}
    	
    	abstract void primitiveOperation1();
    	
    	abstract void primitiveOperation2();
    	
    	final void concreteOperation() {
    		
    	}
    	
    	void hook() {}
    }
    


    面向对象原则:

    好莱坞原则: 别调用我们, 我们会调用你.


    详细方法:

    1. 抽象类(abstract class), 包括模板方法(template method), 抽象操作(abstract operation)

    详细操作(concrete operation), 和钩子(hook).

    /**
     * @time 2014年6月18日
     */
    package template_method;
    
    /**
     * @author C.L.Wang
     *
     */
    public abstract class CaffeineBeverage {
    	
    	final void prepareRecipe() { //模板方法
    		boilWater();
    		brew();
    		pourInCup();
    		if(customerWantsCondiments()) {
    			addCondiments();
    		}
    	}
    	
    	abstract void brew(); //抽象操作
    	
    	abstract void addCondiments();
    	
    	void boilWater() { //详细操作
    		System.out.println("Boiling water");
    	}
    	
    	void pourInCup() {
    		System.out.println("Pouring into cup");
    	}
    	
    	boolean customerWantsCondiments() { //钩子
    		return true;
    	}
    	
    }
    

    2. 详细类(concrete class), 继承(extend) 抽象类(abstract class).

    /**
     * @time 2014年6月18日
     */
    package template_method;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    /**
     * @author C.L.Wang
     *
     */
    public class CoffeeWithHook extends CaffeineBeverage {
    
    	/* (non-Javadoc)
    	 * @see template_method.CaffeineBeverage#brew()
    	 */
    	@Override
    	void brew() {
    		// TODO Auto-generated method stub
    		System.out.println("Dripping Coffee through filter");
    	}
    
    	/* (non-Javadoc)
    	 * @see template_method.CaffeineBeverage#addCondiments()
    	 */
    	@Override
    	void addCondiments() {
    		// TODO Auto-generated method stub
    		System.out.println("Adding Sugar and Milk");
    	}
    	
    	public boolean customerWantsCondiments() { //钩子
    		
    		String answer = getUserInput();
    		
    		if (answer.toLowerCase().startsWith("y")) {
    			return true;
    		} else {
    			return false;
    		}
    		
    	}
    
    	private String getUserInput() {
    		
    		String answer = null;
    		
    		System.out.println("Would you like milk and sugar with your coffee (y/n)? ");
    		
    		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    		
    		try {
    			answer = in.readLine();
    		} catch (IOException ioe) {
    			System.out.println("IO error trying to read your answer");
    		}
    		
    		if (answer == null) {
    			return "no";
    		}
    		
    		return answer;
    	}
    	
    }
    
    
    /**
     * @time 2014年6月18日
     */
    package template_method;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    /**
     * @author C.L.Wang
     *
     */
    public class TeaWithHook extends CaffeineBeverage {
    
    	/* (non-Javadoc)
    	 * @see template_method.CaffeineBeverage#brew()
    	 */
    	@Override
    	void brew() {
    		// TODO Auto-generated method stub
    		System.out.println("Steeping the tea");
    	}
    
    	/* (non-Javadoc)
    	 * @see template_method.CaffeineBeverage#addCondiments()
    	 */
    	@Override
    	void addCondiments() {
    		// TODO Auto-generated method stub
    		System.out.println("Adding Lemon");
    	}
    
    	public boolean customerWantsCondiments() {
    		
    		String answer = getUserInput();
    		
    		if (answer.toLowerCase().startsWith("y")) {
    			return true;
    		} else {
    			return false;
    		}
    		
    	}
    
    	private String getUserInput() {
    		
    		String answer = null;
    		
    		System.out.println("Would you like lemon with your tea (y/n)?

    "); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); try { answer = in.readLine(); } catch (IOException ioe) { System.out.println("IO error trying to read your answer"); } if (answer == null) { return "no"; } return answer; } }


    3. 測试类, 包括钩子(hook)操作.

    /**
     * @time 2014年6月18日
     */
    package template_method;
    
    /**
     * @author C.L.Wang
     *
     */
    public class BeverageTestDrive {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		TeaWithHook teaHook = new TeaWithHook();
    		CoffeeWithHook coffeeHook = new CoffeeWithHook();
    		
    		System.out.println("
    Making tea...");
    		teaHook.prepareRecipe();
    		
    		System.out.println("
    Making coffee...");
    		coffeeHook.prepareRecipe();
    	}
    
    }
    

    4. 输出:

    Making tea...
    Boiling water
    Steeping the tea
    Pouring into cup
    Would you like lemon with your tea (y/n)?

    y Adding Lemon Making coffee... Boiling water Dripping Coffee through filter Pouring into cup Would you like milk and sugar with your coffee (y/n)? n










  • 相关阅读:
    我的访问量咋才3万了
    Khronos发布WebGL标准规范 1.0
    X3Dom V1.2发布
    解决Linux(Fedora Ubuntu)笔记本的待机休眠
    多用户虚拟Web3D环境Deep MatrixIP9 1.04发布
    网络科技公司Web开发团队管理的小结
    XamlReader 动态加载XAML
    Excel Data Reader开源的.NET excel读取库
    .net Sql server 事务的两种用法
    通过使用客户端证书调用 Web 服务进行身份验证{转}
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6731951.html
Copyright © 2011-2022 走看看