模板方法模式(Template Method)
定义一个操作中的算法的框架,而将一些步骤延迟到子类中。 使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤 简单来说就是:定义一个模板,将具体实现推迟到子类中进行重写实现。
简述:
模板方法模式是基于继承
的代码复用
的基本技术,没有关联关系。
在模板方法模式的类结构图中,只有继承关系
代表这些具体逻辑步骤的方法称做基本方法(primitive method)
将这些基本方法汇总起来的方法叫做模板方法(template method)
模板方法实例 下面以煮咖啡味例子,演示模板方法模式以及钩子的用法。
AbstractCoffeeMake
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 public abstract class AbstractCoffeeMake { public void boilingWater () { System.out.println("Boiling water..." ); } public abstract void cookeCoffee () ; public abstract void addSugar () ; public abstract void addMilk () ; public final void make () { this .boilingWater(); this .cookeCoffee(); if (this .needSugar()){ this .addSugar(); } if (this .needMilk()){ this .addMilk(); } } protected boolean needSugar () { return true ; } protected boolean needMilk () { return true ; } }
LatteCoffeeMake
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 public class LatteCoffeeMake extends AbstractCoffeeMake { private boolean needSugar = true ; private boolean needMilk = true ; @Override public void cookeCoffee () { System.out.println("cooke a cup of Latte coffee..." ); } @Override public void addSugar () { System.out.println("add 0.5 cup of sugar to coffee..." ); } @Override public void addMilk () { System.out.println("add 200 ml milk to coffee..." ); } @Override protected boolean needSugar () { return this .needSugar; } @Override protected boolean needMilk () { return this .needMilk; } public void setNeedSugar (boolean needSugar) { this .needSugar = needSugar; } public void setNeedMilk (boolean needMilk) { this .needMilk = needMilk; } }
InstantCoffeeMake
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 public class InstantCoffeeMake extends AbstractCoffeeMake { private boolean needSugar = true ; private boolean needMilk = true ; @Override public void cookeCoffee () { System.out.println("cooke a cup of Instant coffee..." ); } @Override public void addSugar () { System.out.println("add a cup of sugar to coffee..." ); } @Override public void addMilk () { System.out.println("add 100 ml milk to coffee..." ); } @Override protected boolean needSugar () { return this .needSugar; } @Override protected boolean needMilk () { return this .needMilk; } public void setNeedSugar (boolean needSugar) { this .needSugar = needSugar; } public void setNeedMilk (boolean needMilk) { this .needMilk = needMilk; } }
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public static void main (String[] args) { final InstantCoffeeMake coffeeMake = new InstantCoffeeMake(); coffeeMake.setNeedMilk(false ); coffeeMake.make(); final LatteCoffeeMake latteCoffeeMake = new LatteCoffeeMake(); latteCoffeeMake.setNeedSugar(false ); latteCoffeeMake.make(); }
模板方法的优缺点 优点
封装性,封装不变部分,扩展可变部分.
复用性,提取公共部分代码,去除重复代码.
行为由父类控制,子类实现细节,有助于算法的扩展
缺点
每个不同的实现都需要定义一个子类,这会导致类的个数的增加,系统不容易管理。