模板方法模式 详解 设计模式

模板方法模式

模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤延迟到子类中实现。这种模式允许子类在不改变算法结构的情况下重新定义算法的某些步骤。

结构

  • 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。其中包含了一些基本操作的步骤,有些步骤由具体子类实现。

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

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

      • 抽象方法(Abstract Method) :一个抽象方法由抽象类声明、由其具体子类实现。

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

      • 钩子方法(Hook Method) :在抽象类中已经实现,包括用于判断的逻辑方法需要子类重写的空方法两种。

        一般钩子方法是用于判断的逻辑方法,这类方法名一般为isXxx,返回值类型为boolean类型。

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

案例:

你制作一个饮料,步骤是确定的,像烧水; 酿造;倒入杯中,添加调味品。烧水和倒杯是固定的基本操作,酿造和添加调味料这个则是通过具体的情况来定的。

代码实现:

java">// 抽象类
abstract  class Beverage {
    // 模板方法,定义了算法的骨架
    public final void prepareBeverage() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    // 抽象方法,由子类实现
    abstract void brew();
    abstract void addCondiments();

    // 公共方法,由父类实现
    void boilWater() {
        System.out.println("Boiling water");
    }

    void pourInCup() {
        System.out.println("Pouring into cup");
    }
}

// 具体类1
class Coffee extends Beverage {
    @Override
    void brew() {
        System.out.println("Dripping coffee through filter");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding sugar and milk");
    }
}

// 具体类2
class Tea extends Beverage {
    @Override
    void brew() {
        System.out.println("Steeping the tea");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding lemon");
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        Beverage coffee = new Coffee();
        coffee.prepareBeverage();

        System.out.println();

        Beverage tea = new Tea();
        tea.prepareBeverage();
    }
}

注意:为防止恶意操作,一般模板方法都加上 final 关键词。

使用场景:

  • 当有一系列算法步骤,其中有一部分是固定的,但是另一部分需要在子类中具体实现时,可以考虑使用模板方法模式
  • 当需要在不同的子类中重用相同的算法框架时,可以使用模板方法模式

以下是模板方法模式在开发后台管理系统中的使用场景示例:

  1. 权限管理: 在后台管理系统中,通常需要对不同用户或用户组的权限进行管理。模板方法模式可以定义一个权限管理的骨架,包括权限验证、权限分配等操作,而具体的权限验证和分配操作可以交由子类实现。
  2. 数据的增删改查: 后台管理系统通常需要对数据进行增加、删除、修改、查询等操作。可以使用模板方法模式定义一个数据操作的骨架,包括数据的验证、数据的持久化等步骤,而具体的数据操作可以由子类实现。
  3. 数据的导入导出: 后台管理系统可能需要支持数据的导入导出功能,例如从 Excel 文件中导入数据到数据库,或者将数据库中的数据导出为 Excel 文件。可以使用模板方法模式定义一个数据导入导出的骨架,包括数据格式的验证、数据的转换等步骤,而具体的导入导出操作可以由子类实现。
  4. 日志记录: 后台管理系统通常需要记录用户的操作日志,例如登录日志、操作日志等。可以使用模板方法模式定义一个日志记录的骨架,包括日志的格式化、日志的存储等步骤,而具体的日志记录操作可以由子类实现。

优缺点:

优点:

  • 提高代码复用性

    将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。

  • 实现了反向控制

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

缺点:

  • 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
  • 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。

http://www.niftyadmin.cn/n/5401392.html

相关文章

jvm 基础知识和jvm 调优

类装载分为以下 5 个步骤: 加载:根据查找路径找到相应的 class 文件然后导入; 检查:检查加载的 class 文件的正确性; 准备:给类中的静态变量分配内存空间; 解析:虚拟机将常量池中的符…

es7,es8,es9,es10

ES7有哪些新增方法 ES7(ES2016)引入了一些新的特性和方法,其中一些新增的方法包括: Array.prototype.includes(): 判断一个数组是否包含某个特定元素,如果包含则返回 true,否则返回 false。 …

【面试】中科软外包某银行

谈谈对 SpringBoot 的理解? RequestMapping、PostMapping、GetMapping 的理解 RequestMapping注解用于建立请求路径与方法的对应关系。 GetMapping是用于将HTTP Get请求映射到特定处理程序的方法注解具体来说,这是一个组合注解,是RequestM…

ubuntu22.04安裝mysql8.0

官网下载mysql:MySQL :: Download MySQL Community Server 将mysql-server_8.0.20-2ubuntu20.04_amd64.deb-bundle.tar上传到/usr/local/src #解压压缩文件 tar -xvf mysql-server_8.0.20-2ubuntu20.04_amd64.deb-bundle.tar解压依赖包依次输入命令 sudo dpkg -i m…

Java核心卷1笔记

3. Java的基本程序设计结构 3.1 一个简单的Java应用程序 Java区分大小写类名:大写字母开头,每个单词首字母大写源代码文件与公共类名字相同编译得到类字节码文件函数调用:object.method(parameters) 3.2 注释 在Java中,有3种注…

VSCode远程XHR failed无法连接

问题呈现: Resolver error: Error: XHR failed at y.onerror (vscode-file://vscode-app/d:/Microsoft%20VS%20Code/resources/app/out/vs/workbench/workbench.desktop.main.js:77:1261) 问题分析: VSCode进行远程连接时会检查服务端的Server运行情况&a…

微服务简介及其相关技术栈

目录 1、简介 2、技术栈 3、单体架构 4、分布式架构 5、微服务 6、总结 🍃作者介绍:双非本科大三网络工程专业在读,阿里云专家博主,专注于Java领域学习,擅长web应用开发、数据结构和算法,初步涉猎Pyth…

Zynq—AD9238数据采集DDR3缓存千兆以太网发送实验(一)

Zynq—AD9238数据采集DDR3缓存千兆以太网发送实验(前导) 四、AXI转FIFO接口模块设计 1.AXI接口知识 AXI协议是基于 burst的传输,并且定义了以下 5 个独立的传输通道: 读地址通道(Read Address Channel, …