目录

设计模式之模板方法模式

目录

设计模式之模板方法模式

  • 模板方法模式(Template Method)

    • 定义一个操作中的算法骨架,将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤,属于行为型模式
  • 应用场景

    • JavaWeb里面的Servlet,HttpServlet类提供了一个service()方法
    • 有多个子类共有逻辑相同的方法,可以考虑作为模板方法
    • 设计一个系统时知道了算法所需的关键步骤,且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,可以延迟到子类进行完成
  • 角色

    • 抽象模板(Abstract Template):定义一个模板方法,这个模板方法一般是一个具体方法,给出一个顶级算法骨架,而逻辑骨架的组成步骤在相应的抽象操作中,推迟到子类实现

      • 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法
      • 基本方法:是整个算法中的一个步骤,包括抽象方法和具体方法
        • 抽象方法:在抽象类中声明,由具体子类实现
        • 具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它
    • 具体模板(Concrete Template):实现父类所定义的一个或多个抽象方法,它们是一个顶级算法逻辑的组成步骤

      https://i-blog.csdnimg.cn/direct/455051e73b8e4741a4769efa28560dab.png

  • 代码示例,以项目开发上线为例

    /**
     * 抽象模板:包括模板方法和基本方法
     */
    abstract class AbstractProjectManager {
    
        /**
         * 模板方法,使用final不允许重写
         */
        public final void processProject() {
            this.design();
            this.coding();
            this.online();
        }
    
        /**
         * 通用方法,假设任何项目这一步骤都相同
         */
        public void design() {
            System.out.println("项目设计");
        }
    
        /**
         * 抽象方法,假设每个项目编码都不相同
         */
        public abstract void coding();
    
        /**
         * 抽象方法
         */
        public abstract void online();
    }
    
    /**
     * 具体模板:支付服务
     */
    class PayServiceProjectManager extends AbstractProjectManager {
        @Override
        public void coding() {
            System.out.println("支付服务:后端编码");
        }
    
        @Override
        public void online() {
            System.out.println("支付服务:灰度上线");
        }
    }
    
    /**
     * 具体模板:用户服务
     */
    class UserServiceProjectManager extends AbstractProjectManager {
        @Override
        public void coding() {
            System.out.println("用户服务:后端编码+前端编码");
        }
    
        @Override
        public void online() {
            System.out.println("用户服务:先灰度上线,再全量上线");
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            new PayServiceProjectManager().processProject();
            System.out.println("========================");
            new UserServiceProjectManager().processProject();
        }
    }
  • 优点

    • 扩展性好,对不变的代码进行封装,对可变的代码进行扩展,符合开闭原则
    • 提高代码复用性,将相同部分的代码放在抽象的父类中,将不同的代码放入不同的子类中
    • 通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制
  • 缺点

    • 每一个不同的实现都需要一个子类来实现,导致类的个数增加,会使系统变得复杂
  • 模板方法模式和建造者模式区别

    • 两者很大的交集,建造者模式比模板方法模式多了一个指挥类,该类体现的是模板方法模式中抽象类的固定算法的功能,是一个创建对象的固定算法