一、模板模式介绍
在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。它也叫模板方法模式,这种类型的设计模式属于行为型模式。
一般模板方法都加上
final
关键字,防止子类重写模板方法。此处我们有一个诉求:
- 使用模板模式,制作不同口味的牛奶。
二、模板模式使用
2.1 示例关系:
2.2 代码实现:
/* *
* 1. 牛奶抽象类(定义骨架)。
*/
abstract class Milk {
/* *
* final对模板make()方法进行修饰-子类无法覆盖。
*/
final void make() {
getMaterial();
if (isAddTaste()) {
addTaste();
}
wrap();
}
void getMaterial() {
System.out.println(" 纯牛奶原料 ");
}
/* *
* 添加口味的抽象方法-需要子类自己去实现。
*/
public abstract void addTaste();
void wrap() {
System.out.println(" 包装 ");
}
/* *
* 钩子方法-默认不做任何事情,子类可视情况是否需要去覆盖。
*/
boolean isAddTaste() {
return true;
}
}
/* *
* 2. 香蕉牛奶类(具体实现)。
*/
class BananaMilk extends Milk {
@Override
public void addTaste() {
System.out.println(" 添加香蕉口味 ");
}
}
/* *
* 3. 草莓牛奶类(具体实现)。
*/
class StrawberryMilk extends Milk {
@Override
public void addTaste() {
System.out.println(" 添加草莓口味 ");
}
}
/* *
* 4. 原味牛奶类(具体实现)。
*/
class PlainMilk extends Milk {
/* *
* 空实现。
*/
@Override
public void addTaste() {
}
/* *
* 覆盖钩子方法,该类决定不使用添加口味的方法。
*/
@Override
boolean isAddTaste() {
return false;
}
}
/* *
* 5. 客户端调用。
*/
public class Client {
public static void main(String[] args) {
System.out.println(" ======制作香蕉牛奶====== ");
Milk bananaMilk = new BananaMilk();
bananaMilk.make();
// ======制作香蕉牛奶======
// 纯牛奶原料
// 添加香蕉口味
// 包装
System.out.println(" ======制作草莓牛奶====== ");
Milk strawberryMilk = new StrawberryMilk();
strawberryMilk.make();
// ======制作草莓牛奶======
// 纯牛奶原料
// 添加草莓口味
// 包装
System.out.println(" ======制作原味牛奶====== ");
Milk plainMilk = new PlainMilk();
plainMilk.make();
// ======制作原味牛奶======
// 纯牛奶原料
// 包装
}
}
三、模板模式总结
基本思想:
- 算法只存在于一个地方,也就是父类中,当需要修改算法时,只需要修改父类的模板方法或者已经实现的某些步骤,子类就会继承这些修改。
优点:
- 实现了代码的复用。
- 统一了算法,提升了灵活性。
缺点:
- 每一个不同的实现都需要一个子类实现,导致类的个数增加,使得系统更加庞大。
应用场景:
- 当要完成在某个过程,使该过程要执行一系列步骤,这一些列步骤基本相同,但其个别步骤在实现时可能不同,通常考虑用模板模式来处理。
- 调试程序执行时间。
Spring IOC
容器初始化时运用到了该模式。
四、结束语
“-------怕什么真理无穷,进一寸有一寸的欢喜。”
微信公众号搜索:饺子泡牛奶。