HeadFirst 设计模式学习之模板方法模式
2016-06-03 22:34
573 查看
HeadFirst 设计模式学习之模板方法模式
模板方法定义在一个方法中定义一个算法骨架,而将一些步骤延迟到子类中,模板方 法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
demo演示–泡茶和冲咖啡
分析:
泡茶和冲咖啡都可以分成下面四个步骤:
把水烧热
冲泡茶/咖啡
将茶/咖啡倒入杯子
加入合适的调料(茶可以放柠檬,咖啡放糖)
定义算法骨架:
void preparRecipe() { boilWater(); //烧水 brew(); //冲泡 pourInCup(); //倒入杯子 addCondiments();//加调料 }
上面的骨架中,咖啡和茶烧水喝倒入杯子的过程是完全相同的,所以定义在基类中,其他两个方法则有子类负责实现。
基类
abstract class Beverage { public final void preparRecipe() { boilWater(); //烧水 brew(); //冲泡 pourInCup(); //倒入杯子 addCondiments();//加调料 } public abstract void addCondiments(); public void pourInCup() { // TODO Auto-generated method stub System.out.println("pourInCup-------"); } public abstract void brew() ; public void boilWater() { // TODO Auto-generated method stub System.out.println("BoilWater-------"); } }
子类Tea
class Tea extends Beverage { @Override public void addCondiments() { // TODO Auto-generated method stub System.out.println("add Condiment to tea-------"); } @Override public void brew() { // TODO Auto-generated method stub System.out.println("brew tea-------"); } }
咖啡类与茶类相似,代码就不再贴出。
测试代码及结果: public static void main(String[] args) { // TODO Auto-generated method stub new Tea().preparRecipe(); } BoilWater------- brew tea------- pourInCup------- add Condiment to tea-------
再进一步,模板方法与钩子
在上一个部分中,我们定义了一个含有四个部分的算法骨架,其中两个部分交给子类去实现,另外两个由基类实现。这样做,对于基类来说,屏蔽了算法的某些细节,而
4000
子类负责实现这些细节,从而将自己挂载到算法当中去,而钩子则能够改变算法流程。
钩子的魅力——灵活的加入调料
先对上面的基类做出以下修改:
加入方法getAns(),用来得到是否需要调料。
将该方法放入preparRecipe()。
修改完的类:
abstract class Beverage { public final void preparRecipe() { boilWater(); //烧水 brew(); //冲泡 pourInCup(); //倒入杯子 if(getAns()) addCondiments();//加调料 } public abstract void addCondiments(); public void pourInCup() { // TODO Auto-generated method stub System.out.println("pourInCup-------"); } public abstract void brew() ; public void boilWater() { // TODO Auto-generated method stub System.out.println("BoilWater-------"); } public boolean getAns() { return true; //默认是加调料的 } }
Tea类复写方法getAns()
public boolean getAns() { // TODO Auto-generated method stub System.out.println("是否加入调料:(Y/N)"); BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); try { if("Y".equals(in.readLine())) { return true; } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; }
运行结果:
BoilWater------- brew tea------- pourInCup------- 是否加入调料:(Y/N) Y add Condiment to tea-------
上述过程中,子类通过复写了基类的方法来达到改变算法流程的目的(是否执行addCondiments()方法),这就是钩子的用法。
涉及的原则:好莱坞原则
好莱坞原则:别调用我们,我们会调用你。
好莱坞原则是防止“依赖腐败”(高层和低层相互依赖)的方法,它让高层决定流程(什么时候调用低层),低层决定某些细节。
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C# 设计模式系列教程-建造者模式
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解
- 实例解析C#设计模式编程中简单工厂模式的使用
- 详解C#设计模式编程中生成器模式的使用