定义
定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现。
准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。
不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。
适用场景
- 一次性实现一个算法不变的部分,并将可变的行为留给子类来实现。
- 提取子类重复实现的方法,放在超类中。
- 控制子类的扩展,必须遵循这一套流程规则。
案例
这是一个炒菜的案例,贴近生活,简单易懂。
CookTemplate:炒菜的一套模板
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
| public abstract class CookTemplate {
protected void create() { this.pourOil(); this.HeatOil(); this.pourVegetable(); this.pourSauce(); this.fry(); }
public void pourOil() { System.out.println("倒油"); }
public void HeatOil() { System.out.println("热油"); }
public abstract void pourVegetable();
public abstract void pourSauce();
public void fry() { System.out.println("翻炒直到炒熟"); } }
|
CookBaoCai:炒包菜
1 2 3 4 5 6 7 8 9 10 11 12
| public class CookBaoCai extends CookTemplate {
@Override public void pourVegetable() { System.out.println("倒入包菜"); }
@Override public void pourSauce() { System.out.println("加入包菜的调味料"); } }
|
CookHuaCai:炒花菜
1 2 3 4 5 6 7 8 9 10 11
| public class CookHuaCai extends CookTemplate { @Override public void pourVegetable() { System.out.println("倒入花菜"); }
@Override public void pourSauce() { System.out.println("加入花菜的调味料"); } }
|
Test:测试类
1 2 3 4 5 6 7 8 9
| public class TemplateTest { public static void main(String[] args) { CookBaoCai cookBaoCai = new CookBaoCai(); cookBaoCai.create(); System.out.println("====================="); CookHuaCai cookHuaCai = new CookHuaCai(); cookHuaCai.create(); } }
|
优缺点
优点
(1)提高代码复用性。将相同部分的代码放在抽象的超类中。
(2)提高了拓展性。将不同的代码放入不同的子类中,通过对子类的扩展增加新的行为。
(3)实现了反向控制。通过一个父类调用其子类的操作,通过对子类的扩展增加新的行为,实现了反向控制 & 符合“开闭原则”。
缺点
引入了抽象类,每一个不同的实现都需要一个子类来实现,导致类的个数增加,从而增加了系统实现的复杂度。