模版模式
定义
定义了一个算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以在不改变算法结构的情况下,重新定义算法的步骤。模版模式其实很简单,就是一个抽象定义好公共的步骤,把一些单独的算法提取出来。让子类实现。
1>模板模式定义了算法的步骤,把这些步骤的实现延迟到子类
2>模板模式为我们提供了一个代码复用的技巧
3>模板抽象类中可以定义具体方法、抽象方法和钩子方法
4>为了防止子类改变模板中的算法,可以将模板方法声明为final
5>钩子是一种方法,超类中可提供默认实现或者空实现,子类可覆盖或者不覆盖
好莱坞原则,别调用我们,我们会调用你的。模版模式,告诉子类不要调用父类,父类会调用你的。
UML
应用与实例
这个模式在实际情况中也经常用到,比如我们做接口,可能有的步骤是,接收报文,转换报文,同步/异步发送报文,我们用一个抽象类把其他代码逻辑处理好。同步还是异步就是设计成一个钩子,用户可通过重写方法来确定同步还是异步。
集合的compare方法貌似就是用了模版模式 实现compareTo方法即可排序
例子:
我们看一个headfirst这本书里面的例子,煮茶和咖啡
public abstract class Beverage {
/**
* 冲泡咖啡或茶...流程
*/
public final void create(){
boilWater();//把水煮沸
brew();//用沸水冲泡...
pourInCup();//把...倒进杯子
addCoundiments();//加...
}
public abstract void addCoundiments();
public abstract void brew();
public void boilWater() {
System.out.println("煮开水");
}
public void pourInCup() {
System.out.println("倒进杯子");
}
}
茶:
public class Tea extends Beverage{
@Override
public void addCoundiments() {
System.out.println("添加蜂蜜");
}
@Override
public void brew() {
System.out.println("用水冲茶");
}
}
咖啡:略。。。
模版模式的优点:
- 封装不变部分,扩展可变部分。
- 提取公共部分代码,便于维护。
- 行为控制交由子类来实现。
模版模版模式的缺点:
按照我们设计习惯,抽象类负责声明最抽象、最一般的事物属性和方法,实现类完成具体的事物属性和方法,但是模板方法模式却颠倒了,抽象类定义了部分抽象方法,由子类实现,子类执行的结果影响了父类的结果,也就是子类对父类产生了影响,这在复杂的项目中,会带来代码阅读的难度,而且也会让新手产生不适感。
一旦基类的接口发生了变化,每个继承类都得跟着修改才能够继续使用.这就是所谓高耦合与难维护的说法的来源.
模式的使用场景:
- 多个子类有公有的方法,并且逻辑基本相同时。
- 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
- 重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束其行为。
比较模版模式和策略模式
Strategy模式的应用场景是:
1. 多个类的分别只是在于行为不同
2. 你需要对行为的算法做很多变动
3. 客户不知道算法要使用的数据
Template Method模式的应用场景是:
1. 你想将相同的算法放在一个类中,将算法变化的部分放在子类中实现
2. 子类公共的算法应该放在一个公共的类中,避免代码重复
模版模式是提供了一个算法的大纲,让子类实现某些步骤,对算法有更多的控制权,不会有重复的代码,策略模式不是使用继承进行算法实现,而是通过对象组合的方式让用户选择算法实现,改变策略对象,即可改变算法,更富弹性。但使用的对象较多