模板方法模式Template Method
- 定义一个操作中的算法骨架,将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤,属于行为型模式
应用场景
- javaweb里面的Servlet,HttpService类提供了一个service()方法,
- 有多个子类共有逻辑相同的方法,可以考虑作为模板方法
- 设计一个系统时知道了算法所需的关键步骤,且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,可以延迟到子类进行完成
示例代码:
/**
* 抽象类(Abstract Class)
*/
public abstract class AbstractClass {
/**
* 模版方法
*/
public void templateMethod() {
specificMethod();
abstractMethod1();
abstractMethod2();
}
/**
* 具体方法
*/
public void specificMethod() {
System.out.println("抽象类中的具体方法被调用");
}
// 抽象方法1
public abstract void abstractMethod1();
// 抽象方法2
public abstract void abstractMethod2();
}
角色
- 抽象模板(Abstract Template): 定义一个模板方法,这个模板方法一般是一个具体方法,给出一个顶级算法骨架,而逻辑骨架的组成步骤在相应的抽象操作中,推迟到子类实现
- 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法
- 基本方法:是整个算法中的一个步骤,包括抽象方法和具体方
- 抽象方法:在抽象类中申明,由具体子类实现。
- 具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它
- 具体模板(Concrete Template):实现父类所定义的一个或多个抽象方法,它们是一个顶级算法逻辑的组成步骤

需求背景
小滴课堂-老王成功晋升为管理者,但是团队来了很多新兵,由于团队水平参差不齐,经常有新项目进来,但整体流程很不规范。
一个项目的生命周期:需求评审-设计-开发-测试-上线-运维。整个周期里面,需求评审-设计是固定的操作,而其他步骤则流程耗时等是根据项目来定的。
因此老王梳理了一个模板,来规范化项目,他只管核心步骤和项目里程碑产出的结果,具体的工时安排和开发就让团队成员去操作
编码实战
抽象类:
public abstract class AbstractProjectManager {
/**
* 定义模板方法,声明final,防止子类覆盖他,更改顺序,流程是一样复用
*/
public final void processProject(){
review();
degisn();
coding();
test();
online();
}
/**
* 各个项目都需要评审,具体方法
*/
public void review(){
System.out.println("项目需求评审");
}
/**
* 各个项目都需要设计,具体方法
*/
public void degisn(){
System.out.println("UI UE进行设计");
}
/**
* 抽象方法,由就具体子类进行实现,编码耗时不一样
*/
public abstract void coding();
/**
* 抽象方法,由就具体子类进行实现,测试有多种,自动化测试、安全测试、压力测试、手工测试
*/
public abstract void test();
/**
* 抽象方法,由就具体子类进行实现,上线有全量发布,灰度发布,停机发布
*/
public abstract void online();
}
支付的服务
public class PayServiceProjectManager extends AbstractProjectManager {
@Override
public void coding() {
System.out.println("开发耗时30天");
}
@Override
public void test() {
System.out.println("功能测试,安全测试,压力测试");
}
@Override
public void online() {
System.out.println("全量上线");
}
}
用户服务
public class UserServiceProjectManager extends AbstractProjectManager {
@Override
public void coding() {
System.out.println("开发耗时10天");
}
@Override
public void test() {
System.out.println("功能测试,压力测试,还有手工测试");
}
@Override
public void online() {
System.out.println("灰度发布,全量上线");
}
}
Main函数:
public class Main {
public static void main(String[] args) {
AbstractProjectManager projectManager;
projectManager = new PayServiceProjectManager();
projectManager.processProject();
System.out.println("=============");
projectManager = new UserServiceProjectManager();
projectManager.processProject();
}
}
执行结果:
项目需求评审
UI UE进行设计
开发耗时30天
功能测试,安全测试,压力测试
全量上线
=============
项目需求评审
UI UE进行设计
开发耗时10天
功能测试,压力测试,还有手工测试
灰度发布,全量上线
优点
- 扩展性好,对不变的代码进行封装,对可变的进行扩展,符合 开闭原则
- 提高代码复用性 将相同部分的代码放在抽象的父类中,将不同的代码放入不同的子类中
- 通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制
缺点
*每一个不同的实现都需要一个子类来实现,导致类的个数增加,会使系统变得复杂
模板方法模式和建造者模式区别
两者很大的交集,建造者模式比模板方法模式多了一个指挥类,该类体现的是模板方法模式中抽象类的固定算法的功能,是一个创建对象的固定算法
网友评论