一.概念
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
二.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方法。
- 当不变的和可变的方法在子类实现中混在一起的时候,不变的行为就会在子类中重复出现。通过模板方法模式把这些不变的行为搬到单一的地方,可以帮助子类摆脱重复的不变行为的纠缠。