模板模式
模板模式通常又叫模板方法模式(Template Method Pattern)是指定义一个算法的骨架,并允许子类为一个或者多个步骤提供实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤,属于行为性设计模式。模板方法适用于以下应用场景:
一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
各子类中公共的行为被提取出来并集中到一个公共的父类中,从而避免代码重复。
这里还是以平时开发的流程来举例,这里是开发时常接触的一些大体的流程:
- 需求评审
- 需求变更(这里是可变的)
- 设计文档编写
- 开发
- 测试
- 发布
实例
- UML类图
-
工作流程顶层抽象
public abstract class Workflow { protected void write(){ //1. 需求评审 this.requirementReview(); //2. 需求变更(这里是可变的) if(needChange()){ this.requirementChange(); } //3. 设计文档编写 this.writeDesignDoc(); //4. 开发 this.code(); //5. 测试 this.test(); //6. 发布 this.launch(); } //钩子方法,实现对流程的微调 protected boolean needChange() { return false; } private void launch() { System.out.println("功能发布"); } private void test() { System.out.println("测试"); } private void code() { System.out.println("写代码"); } private void writeDesignDoc() { System.out.println("编写设计文档"); } protected abstract void requirementChange(); private void requirementReview() { System.out.println("需求评审"); } }
-
个人中心功能
public class UserModule extends Workflow { @Override protected void requirementChange() { System.out.println("需求变更:开发用户模块需要支持个人信息同步至CRM系统"); } }
-
订单功能
public class OrderModule extends Workflow { private boolean needChange; public OrderModule (boolean needChange){ this.needChange = needChange; } //需求变更 @Override protected void requirementChange() { System.out.println("需求变更:该订单需求需要支持批量删除功能"); } @Override protected boolean needChange() { return true; } }
-
测试
public class WorkflowTest { public static void main(String[] args) { //开发用户模块 Workflow workflow = new UserModule(); workflow.write(); System.out.println("==============================="); //开发订单模块 Workflow workflow2 = new OrderModule(true); workflow2.write(); } }
-
输出
需求评审 编写设计文档 写代码 测试 功能发布 =============================== 需求评审 需求变更:该订单需求需要支持批量删除功能 编写设计文档 写代码 测试 功能发布
上面就是很简单的一个关于模板模式的例子,说下优缺点:
优点:
利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性。
将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性。
把不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台。
符合开闭原则。
缺点:
类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类的个数增加。
类数量的增加,间接地增加了系统实现的复杂度。
继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍