模板方法模式(Template Method) : 指:一个抽象类中,有一个主方法,主方法是处理逻辑的骨架,也就是调用了一系列处理方法.再定义1…n个方法,可以是抽象的,也可以是实际的方法(这些就是处理方法),子类继承该抽象类,重写抽象方法,通过调用抽象类中主方法,实现对子类的调用. 抽象类定义实现模板,子类实现其未实现的具体方法.
作者是个二吊子,如果描述有误请指出.
使用场景
我们有两种订单,一种会员订单,一种普通订单.订单都有生成账单的功能,也都含有金额等计算方法.会员订单具有折扣特权,而普通会员没有.这个时候我们传统做法是定义两种订单,并赋予具体实现,这时候就会产生非常多的重复代码,大量代码冗余会给我们后续的优化以及维护工作带来不可预估的工作量.此时就引出了模板模式.
模板模式中还有一个钩子方法的定义.我们可以在抽象类中定义一个空实现方法,让子类进行选择实现.该方法能够匹配子类的实现,能通过该方法进行处理方法的控制.
模板模式
uml图
这是尚学堂的案例,引用地址下文贴出了.
本案例中,我们定义了SoyaMilk 豆浆的抽象类,定义了模板方法make,其中make为具体实现,这个方法的作用的形成一个调用链,或者理解为封装调用过程.select, soak,beat为通用的实现,都具有的行为.而addCondiments 方法是需要延迟到子类进行具体实现的.这个就是个性化操作了.customerWantCondiments为钩子方法,我们用它来控制流程中的调用逻辑.这里在抽象类中是具体实现,子类可以自定义进行实现.
/**
* @Description: 抽象类,类中实现了模板方法,定义了算法骨架,具体实现延迟到子类实现
* @Author: gaofan
* @Date: 2020/3/26 10:04
* @Copyright: 2020 www.withu.top Inc. All rights reserved.
**/
public abstract class SoyaMilk {
// 不允许子类覆盖
public final void make(){
System.out.println("-------------制作豆浆开始了-------------");
select();
if(customerWantCondiments()){
addCondiments();
}
soak();
beat();
}
public void select(){
System.out.println("第一步: 选择好的黄豆");
}
// 添加辅料
public abstract void addCondiments();
// 浸泡
public void soak(){
System.out.println("第三步: 黄豆和配料开始浸泡,三小时");
}
public void beat(){
System.out.println("第四步: 黄豆和配料放到豆浆机中打碎");
}
// 钩子方法
public boolean customerWantCondiments(){
return true;
}
}
/**
* @Description: 具体实现,子类自行实现算法部分
* @Author: gaofan
* @Date: 2020/3/26 10:05
* @Copyright: 2020 www.withu.top Inc. All rights reserved.
**/
public class PureSoyaMilk extends SoyaMilk {
@Override
public void addCondiments() {
}
@Override
public boolean customerWantCondiments() {
return false;
}
}
/**
* @Description: TODO
* @Author: gaofan
* @Date: 2020/3/26 10:15
* @Copyright: 2020 www.withu.top Inc. All rights reserved.
**/
public class RedBeanSoyaMilk extends SoyaMilk {
@Override
public void addCondiments() {
System.out.println("第二步: 加入上好的红豆");
}
}
/**
* @Description: TODO
* @Author: gaofan
* @Date: 2020/3/26 10:05
* @Copyright: 2020 www.withu.top Inc. All rights reserved.
**/
public class Client {
public static void main(String [] args){
SoyaMilk redBean = new RedBeanSoyaMilk();
redBean.make();
SoyaMilk blackBean = new PureSoyaMilk();
blackBean.make();
}
}
类型: 模板模式
原理: 以方法作为抽象维度.对于具有较多类似方法和流程的结构进行复用和统一.通过抽象类定义一个规范调用过程,其中部分处理抽象,延迟到子类自行实现.这里就能够实现根据各自的场景进行处理了.
本文借鉴尚硅谷Java设计模式,韩顺平图解java,传送门