设计模式-模板模式

2023-12-17 04:48:48
设计模式专栏


模式介绍

模板模式是一种行为型设计模式,它通过将算法的骨架抽象成一个模板方法,将具体的操作留给子类来实现。这种模式的主要思想是将一个行为定义为一个框架,然后由子类填充细节。

在模板模式中,抽象类公开定义了执行它的方法的方式/模板。子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种模式旨在定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。

模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。模板模式封装不变部分,扩展可变部分,提取公共代码,便于维护。同时,行为由父类控制,子类实现。

然而,模板模式也有一些缺点。每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。

模板模式适用于有多个子类共有的方法且逻辑相同的情况,对于重要的、复杂的方法,可以考虑作为模板方法。

在这里插入图片描述

模式特点

模板模式的优点主要包括:

  1. 提高代码复用性 :通过将相同处理逻辑的代码放到抽象类中,可以避免在多个子类中重复编写相同的代码,提高代码的复用性。
  2. 提高代码扩展性 :将不同的代码在不同的子类中实现,通过对子类的扩展增加新的行为,使得代码更加灵活,易于扩展。
  3. 符合开闭原则 :通过将不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台,符合开闭原则。

模板模式的缺点主要包括:

  1. 类数目的增加 :每一个抽象类都需要至少一个子类来实现,这样导致类的个数增加,从而导致系统复杂度的增加。
  2. 继承关系的缺点 :如果父类添加了新的抽象方法,所有子类都要增加该方法,这在一定程度上增加了代码的复杂性和维护成本。

模板模式在一定程度上可以提高代码的复用性和扩展性,但同时也增加了系统的复杂度。因此,在使用模板模式时需要谨慎考虑其优缺点。

在这里插入图片描述

应用场景

模板模式的应用场景主要包括以下几个方面:

  1. 算法骨架:当需要实现一个算法的不变部分,并将可变的行为留给子类来实现时,可以使用模板模式。例如,在排序算法中,比较大小的逻辑是固定的,但具体的排序方法(如冒泡排序、选择排序等)可以由子类来实现。

  2. 公共行为提取:当多个子类中拥有相同的方法,而且逻辑相同时,可以将这些方法抽出来放到一个模板抽象类中。这样可以避免代码重复,提高代码的可维护性和可扩展性。

  3. 主框架相同:当程序主框架相同,细节不同的情况下,也可以使用模板方法。例如,在Web开发中,前后端交互的流程通常是固定的,但具体的业务逻辑可以根据不同的需求来实现。

模板模式适用于那些需要定义一个算法骨架,将一些步骤留给子类来实现的场景。通过提取公共行为和避免代码重复,可以提高代码的可维护性和可扩展性。

在这里插入图片描述

模板模式和工厂模式区别

模板模式和工厂模式是两种不同的设计模式,它们在以下几个方面存在区别:

  1. 目的不同:模板模式的主要目的是通过定义一个抽象类,将一些公共的行为封装在抽象类中,然后通过继承抽象类来实现具体的业务逻辑。而工厂模式的主要目的是通过创建工厂类来管理对象的创建过程,从而降低代码的耦合度。

  2. 适用场景不同:模板模式适用于当系统中存在大量相似的对象,并且这些对象具有公共的行为和属性时。而工厂模式适用于当系统中存在大量相似的对象,并且这些对象的创建过程比较复杂时。

  3. 实现方式不同:模板模式通过继承抽象类来实现具体的业务逻辑,而工厂模式通过创建工厂类来管理对象的创建过程。

  4. 代码结构不同:模板模式的代码结构比较清晰,易于理解和维护。而工厂模式的代码结构相对较为复杂,需要仔细考虑工厂类的设计以及如何管理对象的创建过程。

模板模式和工厂模式在目的、适用场景、实现方式和代码结构等方面存在区别。在使用时需要根据具体的需求和场景来选择合适的设计模式。

在这里插入图片描述

代码示例

Java实现模板模式

以下是Java实现模板模式的示例代码:

// 抽象类,定义模板方法
public abstract class AbstractClass {
    public void templateMethod() {
        doSomething();
        doSomethingElse();
    }

    // 具体方法,由子类实现
    public abstract void doSomething();

    // 具体方法,由子类实现
    public abstract void doSomethingElse();
}

// 具体子类1,实现抽象类中的方法
public class ConcreteClass1 extends AbstractClass {
    @Override
    public void doSomething() {
        System.out.println("ConcreteClass1 do something");
    }

    @Override
    public void doSomethingElse() {
        System.out.println("ConcreteClass1 do something else");
    }
}

// 具体子类2,实现抽象类中的方法
public class ConcreteClass2 extends AbstractClass {
    @Override
    public void doSomething() {
        System.out.println("ConcreteClass2 do something");
    }

    @Override
    public void doSomethingElse() {
        System.out.println("ConcreteClass2 do something else");
    }
}

// 客户端代码,使用模板模式
public class Client {
    public static void main(String[] args) {
        AbstractClass abstractClass1 = new ConcreteClass1();
        abstractClass1.templateMethod(); // 输出:ConcreteClass1 do something\nConcreteClass1 do something else\n
        AbstractClass abstractClass2 = new ConcreteClass2();
        abstractClass2.templateMethod(); // 输出:ConcreteClass2 do something\nConcreteClass2 do something else\n
    }
}

在上面的示例代码中,我们定义了一个抽象类AbstractClass,其中定义了一个模板方法templateMethod(),和两个抽象方法doSomething()doSomethingElse()。然后,我们定义了两个具体子类ConcreteClass1ConcreteClass2,分别实现了抽象类中的方法。最后,在客户端代码中,我们创建了两个具体子类的实例,并调用了它们的模板方法。通过运行程序,我们可以看到,不同的具体子类实现了不同的逻辑,但它们的调用方式是一样的。这就是模板模式的优点之一,它可以将公共的行为封装在抽象类中,从而避免代码的重复和冗余。

python实现模板模式

以下是Python实现模板模式的示例代码:

from abc import ABC, abstractmethod

# 抽象类,定义模板方法
class AbstractClass(ABC):
    @abstractmethod
    def primitive_operation1(self):
        pass

    @abstractmethod
    def primitive_operation2(self):
        pass

    def template_method(self):
        self.primitive_operation1()
        self.primitive_operation2()

# 具体子类1,实现抽象类中的方法
class ConcreteClass1(AbstractClass):
    def primitive_operation1(self):
        print("ConcreteClass1 primitive_operation1")

    def primitive_operation2(self):
        print("ConcreteClass1 primitive_operation2")

# 具体子类2,实现抽象类中的方法
class ConcreteClass2(AbstractClass):
    def primitive_operation1(self):
        print("ConcreteClass2 primitive_operation1")

    def primitive_operation2(self):
        print("ConcreteClass2 primitive_operation2")

# 客户端代码,使用模板模式
if __name__ == '__main__':
    concrete_class1 = ConcreteClass1()
    concrete_class1.template_method()  # 输出:ConcreteClass1 primitive_operation1\nConcreteClass1 primitive_operation2\n
    concrete_class2 = ConcreteClass2()
    concrete_class2.template_method()  # 输出:ConcreteClass2 primitive_operation1\nConcreteClass2 primitive_operation2\n

在这个示例中,我们使用了Python的内置abc模块来定义抽象类和抽象方法。在抽象类AbstractClass中,我们定义了一个模板方法template_method(),并在其中调用了两个抽象方法primitive_operation1()primitive_operation2()。然后,我们定义了两个具体子类ConcreteClass1ConcreteClass2,分别实现了抽象类中的方法。最后,在客户端代码中,我们创建了两个具体子类的实例,并调用了它们的模板方法。通过运行程序,我们可以看到,不同的具体子类实现了不同的逻辑,但它们的调用方式是一样的。这就是模板模式的优点之一,它可以将公共的行为封装在抽象类中,从而避免代码的重复和冗余。

在这里插入图片描述

模板模式在spring中的应用

在Spring框架中,模板模式被广泛应用,以简化常见任务的执行,并提供一种可扩展的方式来处理特定场景下的重复代码。以下是模板模式在Spring中的几个应用示例:

  1. JdbcTemplate :Spring框架中的JdbcTemplate类是使用模板模式的一个典型示例。它封装了常规的数据库访问流程,如连接管理、异常处理等,并提供了简化的方法来执行SQL查询和更新操作。开发人员只需提供SQL语句和必要的参数,而无需关心底层的数据库访问细节。
  2. HibernateTemplate :对于使用Hibernate作为ORM工具的应用程序,Spring提供了HibernateTemplate类。该类封装了Hibernate会话的管理和常见操作,使开发人员能够更方便地执行数据库访问操作,如保存、查询和删除实体对象。
  3. JmsTemplate :对于使用Java消息服务(JMS)的应用程序,Spring提供了JmsTemplate类。该类简化了JMS消息的生产和消费过程,隐藏了底层的JMS API调用和资源管理。开发人员可以使用JmsTemplate发送和接收消息,而无需编写繁琐的JMS代码。
  4. RestTemplate :在Spring中,RestTemplate是用于执行HTTP请求的类。它提供了一种简单的方式来调用RESTful Web服务,封装了HTTP请求的创建、发送和处理过程。开发人员可以使用RestTemplate发送GET、POST、PUT、DELETE等请求,并处理响应结果。

这些模板类在Spring中提供了一致的使用方式和类似的方法签名,使得开发人员能够轻松地执行常见的任务,而无需编写大量的重复代码。同时,它们也提供了扩展点,允许开发人员根据需要进行自定义操作。通过使用这些模板类,开发人员可以更加专注于业务逻辑的实现,而不是底层技术细节的处理。

在这里插入图片描述

文章来源:https://blog.csdn.net/zhangzehai2234/article/details/135039433
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。