编程设计模式之模板方法模式

编程设计模式之模板方法模式

为什么有模板方法模式?

在软件开发中,有时候我们会遇到一些算法框架,其中一些步骤是固定的,而另一些步骤则可能因应用场景不同而变化。如果每次都直接在代码中硬编码这些固定的步骤,会导致代码的重复和扩展困难。模板方法模式就是为了解决这一问题而诞生的。

模板方法模式的设计思路

模板方法模式定义了一个算法的骨架,将具体步骤的实现延迟到子类中。它包含两种类型的方法:

  1. 模板方法(Template Method):定义了算法的骨架,其中包含了算法的主要逻辑,调用了一系列的抽象方法,这些抽象方法需要在具体子类中实现。
  2. 钩子方法(Hook Method):在模板方法中被声明并提供默认实现,子类可以选择性地覆盖它们来扩展或修改算法的行为。

模板方法模式包含三个主要角色:

  1. AbstractClass(抽象类):定义了一个模板方法,其中包含算法的骨架和一些抽象方法,这些抽象方法由具体子类来实现。
  2. ConcreteClass(具体子类):实现了抽象类中的抽象方法,完成算法的具体步骤。
  3. Hook Method(钩子方法):在抽象类中提供了默认的实现,子类可以选择性地覆盖它们。

Java示例代码

下面是一个简单的Java示例代码,演示了模板方法模式的应用:

java 复制代码
// 抽象类
abstract class AbstractClass {
    // 模板方法
    public final void templateMethod() {
        primitiveOperation1();
        primitiveOperation2();
        hookMethod();
    }

    // 基本方法1(抽象方法)
    abstract void primitiveOperation1();

    // 基本方法2(抽象方法)
    abstract void primitiveOperation2();

    // 钩子方法(默认实现)
    void hookMethod() {
        System.out.println("钩子方法默认实现");
    }
}

// 具体子类A
class ConcreteClassA extends AbstractClass {
    @Override
    void primitiveOperation1() {
        System.out.println("具体子类A中的基本方法1的实现");
    }

    @Override
    void primitiveOperation2() {
        System.out.println("具体子类A中的基本方法2的实现");
    }

    @Override
    void hookMethod() {
        System.out.println("具体子类A中的钩子方法的实现");
    }
}

// 具体子类B
class ConcreteClassB extends AbstractClass {
    @Override
    void primitiveOperation1() {
        System.out.println("具体子类B中的基本方法1的实现");
    }

    @Override
    void primitiveOperation2() {
        System.out.println("具体子类B中的基本方法2的实现");
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        AbstractClass concreteClassA = new ConcreteClassA();
        concreteClassA.templateMethod();

        AbstractClass concreteClassB = new ConcreteClassB();
        concreteClassB.templateMethod();
    }
}

SpringBoot工程中如何应用模板方法模式

在SpringBoot工程中,模板方法模式常被用于定义一些基础的流程或骨架,并在具体子类中实现特定的业务逻辑。例如,Spring框架中的JdbcTemplate就是一个典型的模板方法模式的应用。

下面是一个简单的示例,演示了如何在SpringBoot工程中应用模板方法模式:

java 复制代码
import org.springframework.jdbc.core.JdbcTemplate;

// 抽象模板类
abstract class JdbcOperationTemplate {
    protected final JdbcTemplate jdbcTemplate;

    public JdbcOperationTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    // 模板方法
    public final void execute() {
        openConnection();
        doOperation();
        closeConnection();
    }

    // 抽象方法:打开连接
    protected abstract void openConnection();

    // 抽象方法:执行操作
    protected abstract void doOperation();

    // 抽象方法:关闭连接
    protected abstract void closeConnection();
}

// 具体子类:查询操作
class QueryOperation extends JdbcOperationTemplate {
    public QueryOperation(JdbcTemplate jdbcTemplate) {
        super(jdbcTemplate);
    }

    @Override
    protected void openConnection() {
        System.out.println("打开数据库连接");
    }

    @Override
    protected void doOperation() {
        jdbcTemplate.query("SELECT * FROM table", (rs, rowNum) -> {
            // 处理结果集
            return null;
        });
    }

    @Override
    protected void closeConnection() {
        System.out.println("关闭数据库连接");
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(); // 实际项目中应该从Spring容器中注入
        JdbcOperationTemplate operation = new QueryOperation(jdbcTemplate);
        operation.execute();
    }
}

通过这种方式,在SpringBoot工程中,我们可以定义一些通用的数据库操作流程,并通过具体的子类来实现特定的业务逻辑,实现代码的复用和灵活性。

相关推荐
步行cgn2 小时前
YAML 的语法规则
spring boot·后端
骇客野人3 小时前
SpringBoot电商系统用户注册、登录、留存及数据埋点设计与落地实施方案
java·spring boot·后端
IT_陈寒6 小时前
React的状态更新坑得我差点加班到天亮
前端·人工智能·后端
码事漫谈7 小时前
一天搭出 80% 的 Agent,然后卡在 95% 到死
后端
leonkay7 小时前
C# 锁机制——【2】深入原理
开发语言·后端·spring·c#·个人开发
江湖十年7 小时前
在 Go 中使用 dyno 包处理动态对象
后端·面试·go
八角丶7 小时前
Node 网络编程 —— TLS 模块
javascript·后端·node.js
山岚的运维笔记7 小时前
mysql 专业笔记 -- 第 8 章:使用变量
运维·数据库·笔记·后端·学习·mysql·dba
平头哥AI9 小时前
Day 01 | go run 跑通第一个 Go 程序,go build 留下一个能拷走的 exe
开发语言·后端·golang
ZGG00310 小时前
线程池详解:从 7 大参数到生产避坑
java·数据库·后端