Bootstrap

Java设计模式之模板方法(Template Method)模式

模板方法(Template Method)设计模式为子类定义算法的骨架,而将算法中某些步骤的实现延迟到子类中。这使得子类可以在修改算法的结构上有自己的变化。

什么是模板方法模式

模板方法是一种行为设计模式,它描述了一种特殊的代码重用方式,用来定义一个算法的基本骨架,并将某些步骤的实现延迟到子类中。在模板方法中,算法的核心逻辑通常被放在一个抽象类中实现,而具体实现则由子类提供。这可以让不同的子类提供针对同一问题的不同解决方案,从而实现代码复用。

模板方法设计模式的特点是通过抽象类来定义算法的骨架,而具体实现由子类提供。模板方法中一般包含以下几个要素:

  1. 抽象类:定义一个模板方法,其中包含算法的骨架,以及一个或多个抽象方法,这些方法由不同的实现类提供具体实现。

  2. 具体实现类:实现抽象类中的抽象方法,提供具体的算法实现。

通常情况下,模板方法中的抽象类包含一个或多个基本方法和一个模板方法。基本方法是模板方法中的辅助方法,被模板方法和具体实现类公用。而模板方法则是算法的骨架,由抽象类中定义,它调用基本方法,以及由不同的实现类实现的抽象方法,完成算法的实际逻辑。

模板方法模式的使用场景

  1. 一些算法中有共同的步骤,但是每个步骤的实现方法不同,可以使用模板方法设计模式。

  2. 对于那些会有多种实现方法的算法,可以把算法的核心部分放在抽象类中,然后让具体实现类提供特定的实现。

  3. 对于不同的算法,如果想要保持相同的行为或流程,在这种场景下,模板方法设计模式也能够发挥作用。

模板方法模式的代码示例

以下是一个使用模板方法设计模式的Java代码示例。假设我们有一个基类 AbstractClass ,其中包含了一系列基本方法和一个模板方法 templateMethod 。我们还定义了两个子类 ConcreteClass1 和 ConcreteClass2 ,这些子类会重写 AbstractClass 中的一些抽象方法,因为每个子类都有不同的实现方法。

// 定义抽象类
abstract class AbstractClass {
    // 基本方法
    public void operation1() {
        System.out.println("执行操作1");
    }

    public void operation2() {
        System.out.println("执行操作2");
    }

    // 声明为final,避免子类重写模板方法
    public final void templateMethod() {
        // 调用基本方法
        operation1();
        abstractMethod1();
        operation2();
        abstractMethod2();
    }

    // 抽象方法,需要子类实现
    public abstract void abstractMethod1();

    public abstract void abstractMethod2();
}

// 定义具体实现类1
class ConcreteClass1 extends AbstractClass {
    @Override
    public void abstractMethod1() {
        System.out.println("实现类1,重写抽象方法1");
    }

    @Override
    public void abstractMethod2() {
        System.out.println("实现类1,重写抽象方法2");
    }
}

// 定义具体实现类2
class ConcreteClass2 extends AbstractClass {
    @Override
    public void abstractMethod1() {
        System.out.println("实现类2,重写抽象方法1");
    }

    @Override
    public void abstractMethod2() {
        System.out.println("实现类2,重写抽象方法2");
    }
}

在代码示例中, AbstractClass 是模板方法的抽象类,其中包含了基本方法 operation1 和 operation2 ,以及抽象方法 abstractMethod1 和 abstractMethod2 。由于抽象方法在模板方法中被调用,因此需要在具体实现类中提供具体实现。

两个具体实现类 ConcreteClass1 和 ConcreteClass2 都实现了 AbstractClass 中的抽象方法,它们可以根据需要提供不同的实现方法。

下面是一个客户端代码示例,用于实例化不同的具体实现类,并调用它们的模板方法。

public class Client {
    public static void main(String[] args) {
        AbstractClass instance1 = new ConcreteClass1();
        instance1.templateMethod();

        AbstractClass instance2 = new ConcreteClass2();
        instance2.templateMethod();
    }
}

这段示例代码会创建一个 ConcreteClass1 的实例和一个 ConcreteClass2 的实例,并分别调用它们的模板方法 templateMethod()。

当我们运行客户端代码时,会输出以下结果:

执行操作1
实现类1,重写抽象方法1
执行操作2
实现类1,重写抽象方法2

执行操作1
实现类2,重写抽象方法1
执行操作2
实现类2,重写抽象方法2

这表明模板方法实现了一个算法的骨架,并在子类中提供了具体的实现。在这个示例中,抽象类 AbstractClass 中的基本方法 operation1 和 operation2 被模板方法 templateMethod 调用,而抽象方法 abstractMethod1 和 abstractMethod2 则由子类 ConcreteClass1 和 ConcreteClass2 提供了具体的实现。

模板方法模式的实际应用

在实际的开发中,有一些常用的框架和库使用了模板方法(Template Method)设计模式,以下是其中的几个例子:

  1. Servlet:Servlet 是 JavaEE 中常用的 Web 开发框架,它使用了模板方法设计模式来处理 HTTP 请求和响应。在 Servlet 中,抽象类 HttpServlet 定义了模板方法 service(),子类需要继承 HttpServlet 并重写 service() 方法来处理具体的请求和生成响应。

  2. Spring Framework:Spring 是一个广泛使用的应用程序开发框架,其中的一些子框架也使用了模板方法设计模式。比如,在 Spring Web MVC 框架中,HandlerInterceptor 接口定义了多个模板方法,如 preHandle()、postHandle() 和 afterCompletion(),用于处理请求拦截和后置处理等操作。

  3. Hibernate 框架:Hibernate 是一个用于对象关系映射(ORM)的框架,它使用了模板方法设计模式来定义数据库访问的基本骨架。比如,在 Hibernate 中,Session 是一个抽象类,它定义了一系列的模板方法,如 save()、update() 和 delete(),用于执行数据库操作。

  4. Android 开发中的 Activity 和 Fragment:在 Android 开发中,Activity 和 Fragment 是常用的组件,它们在生命周期管理和用户交互等方面使用了模板方法设计模式。比如,在 Activity 中,onCreate()、onStart() 和 onDestroy() 等方法作为模板方法,开发人员可以重写这些方法来提供自己的业务逻辑。

总结

模板方法设计模式通过将算法的骨架放在一个抽象类中实现,然后由具体实现类提供具体实现,从而实现了代码的复用。通过模板方法设计模式,引入了抽象类,大大增加了系统的灵活性和可扩展性。

在实际开发中,应用模板方法设计模式的场景通常是在处理相似但不完全相同的问题时,或在一个基类中定义了处理流程的具体步骤,而这些步骤有时需要子类来实现不同的实现方法等情况。

关注微信公众号:“小虎哥的技术博客”。我们会定期发布关于Java技术的详尽文章,让您能够深入了解该领域的各种技巧和方法,让我们一起成为更优秀的程序员👩‍💻👨‍💻!

;