1.概述
模板模式是一种常用的设计模式,它定义了一个操作中的算法的骨架,将某些步骤延迟到子类中实现。模板模式使得子类可以在不改变算法结构的情况下重新定义算法中的某些步骤。
模板模式中有两个角色:
- 抽象类(Abstract Class):定义模板方法,描述算法的骨架,包含了一系列的步骤,并且有一些步骤是抽象方法,需要由子类实现。
- 实现类(Concrete Class):抽象类的具体实现,实现了抽象方法,完成了算法中的具体步骤。
下面是模板模式的典型实现步骤。
抽象类:
public abstract class AbstractClass { public final void templateMethod() { // 执行算法的骨架 step1(); step2(); step3(); } public abstract void step1(); public abstract void step2(); public abstract void step3(); // 具体方法 public void concreteMethod() { // 具体方法的实现 } }
实现类:
public class ConcreteClass extends AbstractClass { @Override public void step1() { // 实现步骤1 } @Override public void step2() { // 实现步骤2 } @Override public void step3() { // 实现步骤3 } }
使用:
public class Client { public static void main(String[] args) { AbstractClass template = new ConcreteClass(); template.templateMethod(); } }
2.实际业务场景示例
2.1.需求和实现思路
博主以前做过一个场景,以问卷的方式对一个小区的物业服务进行评价,产品上提供的默认实现是将问卷发给业主来进行评价,但产品推广到某个市的时候,该市有定制化需求,问卷不发给业主而是发给上级管理部门,由上级管理部门去巡视,整理两边的流程如下:
产品上的实现:
- 解析保存问卷
- 将问卷分发给业主
- 保存任务
项目上的定制化需求:
- 解析保存问卷
- 将问卷分发到管理部门的角色上
- 保存任务
这时候就可以用到模板模式。
抽象类:
public abstract class TaskServiceBase { //创建任务 public void createTask(){ savePaper(); allocationPaper(); savePaper(); } //保存问卷 private void savePaper(){ //业务逻辑 } //分发问卷的逻辑 public abstract void allocationPaper(); //保存任务 private void saveTask(){ //业务逻辑 } }
针对客户的定制化实现:
public class ProjectTastService extends TaskServiceBase{ public void allocationPaper() { //分发给住户 } }
产品的通用实现:
public class ProductTaskService extends TaskServiceBase{ public void allocationPaper() { //分发给管理部门 } }
2.1.完整代码实现
产品给出的默认实现,使用@Configuration+@Bean的方式进行注入,配合使用@ConditionalOnMissBean来判断是否已经有实现已经注入Spring的IOC,有的话就不注入产品的默认实现:
项目代码中引入产品的依赖:
没有注入自定义的实现时,调用的会是产品上的默认实现:
编写针对客户的定制化实现,用@Service注解将实现注入Spring 的IOC中
生效的会是给客户定制的实现: