模板设计模式在书中定义:
定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤。
通俗点的理解就是 :完成一件事情,有固定的数个步骤,但是每个步骤根据对象的不同,而实现细节不同;就可以在父类中定义一个完成该事情的总方法,按照完成事件需要的步骤去调用其每个步骤的实现方法。每个步骤的具体实现,由子类完成。
网上找到的一个模板模式的类图:
抽象父类(AbstractClass):实现了模板方法,定义了算法的骨架。
具体类(ConcreteClass):实现抽象类中的抽象方法,即不同的对象的具体实现细节。
模板方法模式的意图是,定义一个操作中 的算法的骨架,而将一些步骤的实现延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。我们最常见的就是 Spring 框架里的各种 Template。
实际例子
我们开了个蛋糕店,蛋糕店不能只卖一种蛋糕呀,于是我们决定先卖奶油蛋 糕,芝士蛋糕和慕斯蛋糕。三种蛋糕在制作方式上一样,都包括造型,烘焙和涂 抹蛋糕上的东西。所以可以定义一个抽象蛋糕模型
然后就可以批量生产三种蛋糕
这样一来,不但可以批量生产三种蛋糕,而且如果日后有扩展,只需要继承 抽象蛋糕方法就可以了,十分方便,我们天天生意做得越来越赚钱。突然有一天, 我们发现市面有一种最简单的小蛋糕销量很好,这种蛋糕就是简单烘烤成型就可以卖,并不需要涂抹什么食材,由于制作简单销售量大,这个品种也很赚钱,于是我们也想要生产这种蛋糕。但是我们发现了一个问题,抽象蛋糕是定义了抽象的涂抹方法的,也就是说扩展的这种蛋糕是必须要实现涂抹方法,这就很鸡儿蛋疼了。怎么办?我们可以将原来的模板修改为带钩子的模板。
做小蛋糕的时候通过 flag 来控制是否涂抹,其余已有的蛋糕制作不需要任何 修改可以照常进行。
最后贴出全部源码
/**
* 类说明:抽象蛋糕模型
*/
public abstract class AbstractCake {
protected abstract void shape();
protected abstract void apply();
protected abstract void brake();
/*模板方法*/
// public final void run(){
// this.shape();
// this.apply();
// this.brake();
// }
/*模板方法*/
public final void run(){
this.shape();
if(this.shouldApply()){
this.apply();
}
this.brake();
}
protected boolean shouldApply(){
return true;
}
}
/**
* 类说明:芝士蛋糕
*/
public class CheeseCake extends AbstractCake {
@Override
protected void shape() {
System.out.println("芝士蛋糕造型");
}
@Override
protected void apply() {
System.out.println("芝士蛋糕涂抹");
}
@Override
protected void brake() {
System.out.println("芝士蛋糕烘焙");
}
}
/**
* 类说明:奶油蛋糕
*/
public class CreamCake extends AbstractCake {
@Override
protected void shape() {
System.out.println("奶油蛋糕造型");
}
@Override
protected void apply() {
System.out.println("奶油蛋糕涂抹");
}
@Override
protected void brake() {
System.out.println("奶油蛋糕烘焙");
}
}
/**
* 类说明:
*/
public class MouseCake extends AbstractCake {
@Override
protected void shape() {
System.out.println("慕斯蛋糕造型");
}
@Override
protected void apply() {
System.out.println("慕斯蛋糕涂抹");
}
@Override
protected void brake() {
System.out.println("慕斯蛋糕烘焙");
}
}
/**
* 类说明:小蛋糕
*/
public class SmallCake extends AbstractCake {
private boolean flag = false;
public void setFlag(boolean shouldApply){
flag = shouldApply;
}
@Override
protected boolean shouldApply() {
return this.flag;
}
@Override
protected void shape() {
System.out.println("小蛋糕造型");
}
@Override
protected void apply() {
System.out.println("小蛋糕涂抹");
}
@Override
protected void brake() {
System.out.println("小蛋糕烘焙");
}
}
/**
* 类说明:生产蛋糕
*/
public class MakeCake {
public static void main(String[] args) {
AbstractCake cake = new CheeseCake();
AbstractCake cake2 = new CreamCake();
//AbstractCake cake = new MouseCake();
cake.run();
AbstractCake smalCake = new SmallCake();
smalCake.run();
}
}