一、简介
1)模板方法模式,Template Method Pattern,又称为模板模式,Template Pattern,即在一个抽象类中公开定义了它的方法的模板。其子类可以按需重写方法实现。
2)模板方法模式属于行为型模式。
二、实现
1)模板方法类
package com.giser.designpattern.template;
/**
* @Note {模板方法模式}
* @author giserDev
* @Date 2020-06-05 21:52:51
*/
abstract public class SoyaMilk {
/**
* @Note {
* 模板方法
* 定义为final,防止子类覆盖
* }
* @author giserDev
* @Date 2020-06-05 21:53:23
*/
final void make() {
select();
addCondiments();
soak();
beat();
}
private void beat() {
System.out.println("第四步:黄豆和配料放到豆浆机去打碎 ");
}
private void soak() {
System.out.println("第三步, 黄豆和配料开始浸泡, 需要3小时");
}
/**
* @Note {抽象方法,由子类具体实现,添加不同的配料}
* @author giserDev
* @Date 2020-06-05 21:56:19
*/
abstract void addCondiments();
private void select() {
System.out.println("第一步,选择新鲜黄豆");
}
}
2)子类
package com.giser.designpattern.template;
public class PeanutSoyaMilk extends SoyaMilk {
@Override
void addCondiments() {
System.out.println("加入花生");
}
}
package com.giser.designpattern.template;
public class RedBeanSoyaMilk extends SoyaMilk {
@Override
void addCondiments() {
System.out.println("加入红豆");
}
}
测试:
package com.giser.designpattern.template;
public class Client {
public static void main(String[] args) {
System.out.println("----制作红豆豆浆----");
SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk();
redBeanSoyaMilk.make();
System.out.println("----制作花生豆浆----");
SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
peanutSoyaMilk.make();
}
}
3)模板方法模式的钩子方法
在模板方法模式的父类中,可以定义一个默认的方法,由子类依据实际情况进行覆盖处理,这种方法称为“钩子”方法。
package com.giser.designpattern.template.improve;
/**
* @Note {模板方法模式}
* @author giserDev
* @Date 2020-06-05 21:52:51
*/
abstract public class SoyaMilk {
/**
* @Note {
* 模板方法
* 定义为final,防止子类覆盖
* }
* @author giserDev
* @Date 2020-06-05 21:53:23
*/
final void make() {
select();
if (customerCondiments()) {
addCondiments();
}
soak();
beat();
}
/**
* @Note {钩子方法:默认实现,是否添加配料}
* @author giserDev
* @Date 2020-06-05 22:55:47
*/
protected boolean customerCondiments() {
return true;
}
private void beat() {
System.out.println("第四步:黄豆和配料放到豆浆机去打碎 ");
}
private void soak() {
System.out.println("第三步, 黄豆和配料开始浸泡, 需要3小时");
}
/**
* @Note {抽象方法,由子类具体实现,添加不同的配料}
* @author giserDev
* @Date 2020-06-05 21:56:19
*/
abstract void addCondiments();
private void select() {
System.out.println("第一步,选择新鲜黄豆");
}
}
package com.giser.designpattern.template.improve;
public class PureSoyMilk extends SoyaMilk {
@Override
void addCondiments() {
// do nothing
}
/**
* 重写钩子方法
*/
@Override
protected boolean customerCondiments() {
return false;
}
}
三、注意事项和细节
1)模板方法使得算法较为集中,即在父类中,便于修改。
2)实现了代码的最大化复用。
3)一般模板方法上需要加final关键字,防止子类重写模板方法。
4)不足之处:每个不同实现都需要一个子类,会导致类个数较多,系统庞大。
5)模板模式的使用场景:当完成执行一系列步骤的某个过程时,除个别步骤不同,通常考虑使用模板方法模式。