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

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

为什么有模板方法模式?

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

模板方法模式的设计思路

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

  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工程中,我们可以定义一些通用的数据库操作流程,并通过具体的子类来实现特定的业务逻辑,实现代码的复用和灵活性。

相关推荐
cyforkk7 小时前
Spring Boot @RestController 注解详解
java·spring boot·后端
canonical_entropy8 小时前
可逆计算:一场软件构造的世界观革命
后端·aigc·ai编程
重庆穿山甲8 小时前
从0到1:用 Akka 持久化 Actor + Outbox + RocketMQ 做到“订单-库存最终一致”
后端
我不只是切图仔9 小时前
我只是想给网站加个注册验证码,咋就那么难!
前端·后端
专注VB编程开发20年9 小时前
CSS 的命名方式像是 PowerShell 的动词-名词结构,缺乏面向对象的层级关系
开发语言·后端·rust
野犬寒鸦9 小时前
力扣hot100:相交链表与反转链表详细思路讲解(160,206)
java·数据结构·后端·算法·leetcode
爱吃烤鸡翅的酸菜鱼10 小时前
【Spring】原理:Bean的作用域与生命周期
后端·spring
JohnYan10 小时前
工作笔记 - 微信消息发送和处理
javascript·后端·微信