一.概念
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
二.UML
- AbstractClass(定义了算法的骨架)。
- ConcreteClass(定义了算法估计中具体算法的实现)。
三.实例分析
做菜,对我来说是相当的简单。我做菜,都是一个流程:洗菜-放油-放菜-放盐-小炸一下-小煮一下-...。做鱼和做肉,除了最后鱼肉的差别外,其它的辣椒颜色,味道什么的,毫无差别。就拿这个例子来说明今天的模式。
Cook
package com.zzy.templateMethod; /** * 做菜 * @author eason * */ public abstract class Cook { //final以免子类改变这个方法的顺序 //我觉得是没必要的,子类不会关注cook方法, //只会关注cook里面调用的每一个方法 public final void cook() { prepare(); putOil(); putFood(); putCondiments(); waitAMoment(); if(!tasteDelicious()) { doOtherThings(); } } //准备工作 public void prepare(){ System.out.println("买菜洗菜等装备工作"); } //放油 public abstract void putOil(); //放菜 public abstract void putFood(); //放作料 public void putCondiments() { System.out.println("放盐,酱油,醋"); } //等待 public abstract void waitAMoment(); //品尝是否美味,默认美味,子类不需要重写此方法 //如果不美味,子类重写此方法即可 public boolean tasteDelicious(){ return true; } //做点其它的事情,让味道更好 public void doOtherThings(){ } }
CookFish
package com.zzy.templateMethod; /** * 做鱼 * @author eason * */ public class CookFish extends Cook { @Override public void putOil() { System.out.println("放花生油"); } @Override public void putFood() { System.out.println("放鱼"); } @Override public void waitAMoment() { System.out.println("等待十分钟"); } }
CookEgg
package com.zzy.templateMethod; /** * 做鸡蛋 * @author eason * */ public class CookEgg extends Cook { @Override public void putOil() { System.out.println("放猪油"); } @Override public void putFood() { System.out.println("放鸡蛋"); } @Override public void waitAMoment() { System.out.println("等待四分钟"); } @Override public boolean tasteDelicious() { return false; } @Override public void doOtherThings(){ System.out.println("做点其它的事情,让味道更好"); } }
TestTemplateMethod
package com.zzy.templateMethod; /** * 测试类 * @author eason * */ public class TestTemplateMethod { public static void main(String[] args) { Cook fish = new CookFish(); fish.cook(); Cook egg = new CookEgg(); egg.cook(); } }
四.使用场景及使用感受
- 模板定义了一系列算法的步骤,这一系列算法中肯定有一个抽象的算法,也就是模板方法是一个工作的概要,至于一套完完整整的工作,是需要子类来参与的。
- 如果对这一系列的算法,有些子类不需要其中的某一个或者某一些算法,可以用"挂钩"来实现,钩子说明了算法的可选性。模板类里面定义这些算法的默认实现或者空实现,子类有需要的话就重写这些算法。如上述中的tasteDelicious方法和doOtherThings方法。
- 当不变的和可变的方法在子类实现中混在一起的时候,不变的行为就会在子类中重复出现。通过模板方法模式把这些不变的行为搬到单一的地方,可以帮助子类摆脱重复的不变行为的纠缠。