1 基础知识
1.1 标准定义
模板方法(Template Method)模式标准定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
1.2 分析和说明
模板方法(Template Method)模式属于行为型设计模式。模板方法模式准备一个抽象类,将部分逻辑以具体方法以及具体构造子的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。也即是先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。
模板方法(Template Method)模式结构如图1所示,其角色包括抽象模版(Abstract Class)角色和具体模版(Concrete Class)角色。
图1 模板方法模式结构
抽象模版(Abstract Class)角色有如下的责任:定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。
具体模版(Concrete Class)角色有如下的责任:实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤。
每一个抽象模版角色都可以有任意多个具体模版角色与之对应,而每一个具体模版角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。
2 应用场景举例
比如公司研发项目的过程是可行性研究、需求分析、总体设计、详细设计、系统编码、系统测试、系统部署、系统维护等标准过程。这些可以形成一个接口,但是为了简化工作,可以形成一个抽象的模板类。把这些步骤全部都实现,如果不能实现,那就使用抽象方法。现在有某给具体项目,其中的总体设计和详细设计与模板不同,这就可以采用模板方法模式。用例见图2所示。
图2 模板方法模式用例图
在这里可以把ProjectProcessTemplate抽象类理解为抽象模版(Abstract Class)角色。ProjectA类和 ProjectB类是具体模版(Concrete Class)角色。其结构类图如图3所示。ProjectA类和 ProjectB类都继承ProjectProcessTemplate抽象类并实现ProjectProcess接口。
图3 模板方法模式类图
模板方法模式实现顺序图见图4,实现顺序描述:
①基于ProjectA创建一个project1对象;
②调用project1对象的doActualWork方法,形成project1对象的项目过程;
③调用project1对象的showProcess方法显示project1对象的项目过程。
图4 模板方法模式实现顺序图
ProjectProcessTemplate抽象类定义一个操作中的算法的骨架,具体实现步骤延迟到子类ProjectA类和 ProjectB类中。
3.Java的实现程序代码
Java程序实现主要包括ProjectProcess接口文件,ProjectProcessTemplate抽象类文件,ProjectA类文件和ProjectB类文件等4个文件。其关系如图3所示。下面分别列出这4个文件的程序代码,最后列出测试代码并显示输出结果。
ProjectProcess接口程序代码清单01所示。
程序代码清单01
public interface ProjectProcess { // 可行性分析过程 public void feasibilityProcess(String content); // 技术交流过程 public void technicalDiscussionProcess(String content); // 投标过程 public void bidProcess(String content); // 需求调研和分析过程 public void requirementProcess(String content); // 设计过程 public void designProcess(String content); // 编码过程 public void programProcess(String content); // 测试过程 public void testProcess(String content); // 部署和实施过程 public void deploymentProcess(String content); // 维护过程 public void maintenanceProcess(String content); public void doActualWork(); public void showProcess(); } |
ProjectProcessTemplate抽象类程序代码清单02所示。
程序代码清单02
public abstract class ProjectProcessTemplate { public Map<String, String> processMap = new HashMap<String, String>(); // 可行性分析过程 public void feasibilityProcess(String content) { processMap.put("feasibilityProcess", content); } // 技术交流过程 public void technicalDiscussionProcess(String content) { processMap.put("technicalDiscussionProcess", content); } // 投标过程 public void bidProcess(String content) { processMap.put("bidProcess", content); } // 需求调研和分析过程 public void requirementProcess(String content) { processMap.put("requirementProcess", content); } // 设计过程 public void designProcess(String content) { processMap.put("designProcess", content); } // 编码过程 public void programProcess(String content) { processMap.put("programProcess", content); } // 测试过程 public void testProcess(String content) { processMap.put("testProcess", content); } // 部署和实施过程 public void deploymentProcess(String content) { processMap.put("deploymentProcess", content); } // 维护过程 public void maintenanceProcess(String content) { processMap.put("maintenanceProcess", content); } public void showProcess() { String key = null; String value = null; Iterator<String> it = processMap.keySet().iterator(); while (it.hasNext()) { key = it.next(); value = processMap.get(key); System.out.println("过程: " + key + "; 内容: " + value); } } } |
ProjectA类继承ProjectProcessTemplate抽象类并实现ProjectProcess接口,其程序代码清单03所示。
程序代码清单03
public class ProjectA extends ProjectProcessTemplate implements ProjectProcess { public void doActualWork() { feasibilityProcess("定制可行性研究"); technicalDiscussionProcess("定制技术交流"); bidProcess("定制投标"); requirementProcess("定制需求"); designProcess("定制设计"); programProcess("定制编码"); testProcess("定制测试"); deploymentProcess("定制部署"); maintenanceProcess("定制维护"); } } |
ProjectB类继承ProjectProcessTemplate抽象类并实现ProjectProcess接口,其程序代码清单04所示。
程序代码清单04
public class ProjectB extends ProjectProcessTemplate implements ProjectProcess { public void doActualWork() { requirementProcess("定制需求"); designProcess("定制设计"); programProcess("定制编码"); testProcess("定制测试"); deploymentProcess("定制部署"); maintenanceProcess("定制维护"); } } |
模板方法模式测试程序的代码清单05如下:
程序代码清单05
public class Client { public static void main(String[] args) { System.out.println("——————projectA的过程——————"); ProjectA project1 = new ProjectA(); project1.doActualWork(); project1.showProcess(); System.out.println("——————projectB的过程——————"); ProjectB project2 = new ProjectB(); project2.doActualWork(); project2.showProcess(); } } |
模板方法模式测试类输出结果如下所示:
——————projectA的过程—————— 过程: deploymentProcess; 内容: 定制部署 过程: maintenanceProcess; 内容: 定制维护 过程: requirementProcess; 内容: 定制需求 过程: designProcess; 内容: 定制设计 过程: programProcess; 内容: 定制编码 过程: bidProcess; 内容: 定制投标 过程: testProcess; 内容: 定制测试 过程: feasibilityProcess; 内容: 定制可行性研究 过程: technicalDiscussionProcess; 内容: 定制技术交流 ——————projectB的过程—————— 过程: deploymentProcess; 内容: 定制部署 过程: maintenanceProcess; 内容: 定制维护 过程: requirementProcess; 内容: 定制需求 过程: designProcess; 内容: 定制设计 过程: programProcess; 内容: 定制编码 过程: testProcess; 内容: 定制测试 |
参考链接
11种行为型模式:
Gof23种设计模式(13)——解释器模式(Interpreter)
Gof23种设计模式(14)——模板方法模式(Template Method)
Gof23种设计模式(15)——责任链模式(Chain of Responsibility)
Gof23种设计模式(16)——命令模式(Command)
Gof23种设计模式(17)——迭代器模式(Iterator)
Gof23种设计模式(18)——中介者模式(Mediator)
Gof23种设计模式(19)——备忘录模式(Memento)
Gof23种设计模式(20)——观察者模式(Observer)
Gof23种设计模式(21)——状态模式(State)
Gof23种设计模式(22)——策略模式(Strategy)
Gof23种设计模式(23)——访问者模式(Visitor)
Gof23种设计模式 —— 行为型模式总结和比较
回到总目录:Gof23种设计模式(全解析)
(转载自微信公众号:架构设计模式)