当前位置: 首页 > article >正文

设计模式——模板方法模式

是什么?

        在我们的实际开发中尝尝会遇到这种问题:在设计一个系统时知道了算法所需要的关键步骤,而且确定了这些步骤的执行顺序,但是某些步骤的具体实现还不知道,或者说某些步骤的实现与具体的环境相关,例如每个人订车,最开始的流程都是相同的:预约、到店、取号、排队、办理业务,这些流程对于每个客户都是相同的,但是办理业务这个流程对于每个客户都可能是不同的,比如有的客户是来订车,有的客户是来进行保养,而有的客户是来更换配饰;

        因此模板方法模式是定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤

结构

抽象类:负责给出一个算法的轮廓和骨架,它由一个模板方法和若干个基本方法构成;

  模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法;

  基本方法:是实现算法各个步骤的方法,是模板方法的组成部分,基本方法又可以分为以下三种:

        抽象方法:一个抽象方法由抽象类声明、由其具体子类实现;

        具体方法:一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承;

        钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种,一般钩子方法是用于判断的逻辑方法,这类方法名一般为isXxx,返回值为boolean类型;

具体子类:实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的组成步骤;

实现

抽象类

public abstract class TemplateAbstractCar {

    /**
     * 模板方法模式中的抽象类
     * 已经实现的方法均为基本方法
     * */
    //预约服务
    public void book(){
       System.out.println("预约服务");
   };
   //到店服务
   public void arrival(){
       System.out.println("客户到店");
   };
   //取号
    public void takeNumber(){
        System.out.println("客户取号");
    };
    //排队服务
    public void line(){
        System.out.println("客户排队");
    }
    //客户具体操作
    protected abstract void buyCar();

    protected  boolean isBuyCar(){
        return false;
    };

    protected abstract void maintain();

    protected boolean isMaintain(){
        return false;
    };

    //空方法
    public void hook(){

    }
    public final void run(){
        //启动四个基本方法
        book();
        arrival();
        takeNumber();
        line();
        //根据子类是否实现了具体方法和钩子方法来判断是否启动
        if (isBuyCar()){
            buyCar();
        }
        if (isMaintain()){
            maintain();
        }
        hook();
    }
}

具体子类

public class Customer extends TemplateAbstractCar{
    @Override
    protected void buyCar() {
        System.out.println("客户1买车服务完毕");
    }

    @Override
    protected void maintain() {

    }

    @Override
    protected boolean isBuyCar() {
        return true;
    }
}

public class Customer2 extends TemplateAbstractCar{
    @Override
    protected void buyCar() {

    }

    @Override
    protected void maintain() {
        System.out.println("客户2保养服务完成");
    }

    @Override
    protected boolean isMaintain() {
        return true;
    }

    @Override
    public void hook() {
        System.out.println("客户二最后还回来买了一辆车");
    }
}

优缺点

   优点

1.提高代码的复用性,将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中;

2.实现了反向控制,通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制,并符合“开闭原则”;

   缺点

1.对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象;

2.父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度;

使用场景

因此在当算法的整体步骤很固定,但其中个别部分容易变时,可以使用模板方法模式,将容易变的部分抽象出来,供子类实现,或者是需要通过子类来决定父类算法中的某个步骤是否执行以实现子类对父类的反向控制时也可以使用;


http://www.kler.cn/a/17911.html

相关文章:

  • Scala学习记录,case class,迭代器
  • HBase理论_背景特点及数据单元及与Hive对比
  • 爱普生SG-8200CJ可编程晶振在通信设备中的应用
  • 智能电视/盒子的应用管理——通过ADB工具优化体验
  • Blender进阶:图像纹理节点和映射节点
  • MYSQL 库,表 基本操作
  • 数据结构与算法基础(王卓)(35):交换排序之快排【第二阶段:标准答案、初步发现问题】
  • 看不懂具体的代码方法?这样向chatgpt提问
  • (22)目标检测算法之 yolov8模型导出总结
  • Scala Option类型,异常处理,IO,高阶函数
  • Ceph入门到精通-OSD 故障排除
  • TCP/IP相关面试题
  • 什么是数据库中的流程控制
  • gpt.4.0-gpt 国内版
  • 华为网工实验(VRRP多网关负载分担,OSPF基础操作)
  • Spring更简单的存取Bean
  • php 设置meta标签中的keywords | description | content-type | copyright的方法函数
  • 字符设备驱动
  • [架构之路-187]-《软考-系统分析师》-5-数据库系统 - 操作型数据库OLTP与分析型数据库OLAP比较
  • Pytorch, tensor存储机制
  • 多元统计分析-聚类分析的原理与应用
  • 大数据技术之SparkSQL——数据的读取和保存
  • springboot+jsp商务安全邮箱(源码+文档)
  • Python代码学习之给图片添加文字或图片水印
  • UPF learing3:TRANS-11
  • python:可以求解Ax=b的库