版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhou6282610/article/details/87688047
概念
模版模式在一个方法中定义一个算法骨架,而将一些父类的步骤抽离到自擂中进行实现,从而将定义父类模版中的某些步骤延迟到子类中进行。
下面以做饭作为例子
首先,我们创建一个做饭的父类:
public abstract class Cook {
/**
* 钩子开关
*/
public boolean needBeforeCook = true;
public boolean needAfterCook = true;
public void open() {
System.out.println("打开抽油烟机...");
}
public void fire() {
System.out.println("生火");
}
/**
* 需要子类实现
*/
public abstract void doCook();
public void outfire() {
System.out.println("灭火");
}
public void close() {
System.out.println("关闭抽油烟机...");
}
public void beforeCook() {
}
public void afterCook() {
}
/**
* 使用final防止子类重写
*/
public final void cook() {
if (this.needBeforeCook) {
beforeCook();
}
this.open();
this.fire();
this.doCook();
this.outfire();
this.close();
if (this.needAfterCook) {
afterCook();
}
}
}
观察其中,可以发现,首先做饭常用的方法我们抽离到父类进行实现,而至于需要做什么菜,我们doCook用abstract修饰,让子类去实现,然后,还加入了beforeCook和afterCook进行保留操作,使得模版加入前后置操作,实现更灵活。而cook使用final防止了子类的重写。再引入钩子开关,来应对不同业务开关前后置操作的执行。
然后,比如我们要炒西红柿,那么创建子类来继承父类模版:
public class CookXiHongShi extends Cook {
@Override
public void beforeCook() {
super.beforeCook();
System.out.println("切西红柿");
}
@Override
public void doCook() {
System.out.println("炒西红柿中...");
}
}
我们开始炒西红柿:
public static void main(String[] args) {
Cook cook = new CookXiHongShi();
cook.needBeforeCook = false;
cook.cook();
}
总结
从这个例子我们看出,当炒菜做饭的时候,除了制作的东西不变,其他操作相同的部分我们抽离了一个父类,这样我们就不需要写大量重复的代码,只需要在根据需要制作什么的时候,增加一个子类来实现这个模版就可以进行炒菜。在HttpServlet中也应用到了模版方法。
优点和缺点
优点:封装不变的公共代码,便于维护。可变部分由子类进行实现,扩展性强。
缺点:每新增一个不同的实现需要增加一个子类,可能导致创建的子类越来越多,增加了系统的复杂性。