设计模式:模板方法模式

2023-09-19 09:38:25


模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个算法的骨架,将某些步骤的具体实现延迟到子类中。模板方法模式通过将共同的行为放在父类中,而将具体的实现交给子类来完成,从而实现了代码的复用和扩展。
在模板方法模式中,父类定义了一个模板方法,该方法中包含了算法的骨架,以及一些基本的步骤。这些步骤可以是具体的实现,也可以是抽象的方法,由子类来实现。子类通过继承父类并重写其中的抽象方法,来完成具体步骤的实现。
模板方法模式的核心思想是通过抽象父类定义算法的骨架,将可变的部分延迟到子类中来实现。这样可以在不改变算法结构的情况下,通过不同的子类来实现不同的具体步骤,实现了代码的复用和扩展。

组件

模板方法模式通常包含以下组件:

  1. 抽象类(Abstract Class):抽象类定义了模板方法,即具有预定义结构的主要算法。它可能还包含抽象方法或默认实现,用于由子类实现的步骤。
  2. 具体类(Concrete Classes):这些是从抽象类继承并提供了抽象类中定义的抽象方法实现的子类。每个具体类可以根据需要改变步骤的实现,同时遵循模板方法定义的结构。
  3. 钩子方法(Hook Methods):这些是抽象类中的可选方法,提供了默认实现,但可以被子类重写(覆盖)的方法。钩子方法允许子类自定义算法中的某些步骤,而不改变整体结构。
  4. 客户端(Client):客户端与抽象类中定义的模板方法进行交互。它创建具体类的实例并调用模板方法来执行算法。
    模板方法模式允许抽象类定义算法的整体结构,同时将某些步骤的实现委托给子类。这促进了代码的重用,允许在实现上有所变化,并提供了在不同子类之间保持一致的算法结构。

代码示例

abstract class AbstractClass {
    // 模板方法,定义算法的整体结构
    public void templateMethod() {
        step1();
        step2();
        step3();
    }
     // 抽象方法,由子类实现的步骤
    protected abstract void step1();
    protected abstract void step2();
     // 钩子方法,可选的步骤,子类可以选择是否重写
    protected void step3() {
        System.out.println("AbstractClass: 默认实现的step3");
    }
}
 // 具体类A
class ConcreteClassA extends AbstractClass {
    protected void step1() {
        System.out.println("ConcreteClassA: 实现step1");
    }
     protected void step2() {
        System.out.println("ConcreteClassA: 实现step2");
    }
}
 // 具体类B
class ConcreteClassB extends AbstractClass {
    protected void step1() {
        System.out.println("ConcreteClassB: 实现step1");
    }
     protected void step2() {
        System.out.println("ConcreteClassB: 实现step2");
    }
     protected void step3() {
        System.out.println("ConcreteClassB: 重写的step3");
    }
}
 // 客户端代码
public class Main {
    public static void main(String[] args) {
        AbstractClass classA = new ConcreteClassA();
        classA.templateMethod();
         System.out.println("-----------------------");
         AbstractClass classB = new ConcreteClassB();
        classB.templateMethod();
    }
}

在上述示例中,我们定义了一个抽象类(AbstractClass),其中包含了模板方法(templateMethod)和抽象方法(step1和step2)。具体类A(ConcreteClassA)和具体类B(ConcreteClassB)分别继承抽象类,并实现了抽象方法。类A和类B可以根据需要改变步骤的实现,并且可以选择是否重写钩子方法(step3)。在客户端代码中,我们创建了具体类的实例并调用模板方法来执行算法。

这个示例展示了如何使用Java实现模板方法模式,通过抽象类定义算法的整体结构,并将某些步骤的实现留给具体类来完成。

源码中使用

在源码中,模板方法模式有很多应用。以下是一些常见的源码中使用模板方法模式的情况:

  1. Java中的Servlet:Java Servlet API中的HttpServlet类就是使用了模板方法模式。HttpServlet类定义了doGet()和doPost()等抽象方法,具体的Servlet类继承HttpServlet并实现这些抽象方法来处理HTTP请求。
  2. Spring框架中的JdbcTemplate:JdbcTemplate是Spring框架中用于简化数据库访问的类。JdbcTemplate类使用了模板方法模式,定义了execute()等模板方法,具体的数据库操作由子类实现。
  3. Android开发中的Activity生命周期:Android的Activity类中的生命周期方法,如onCreate()、onStart()等,也是使用了模板方法模式。Activity类定义了这些生命周期方法,子类可以根据需要重写这些方法来执行自定义的逻辑。
  4. JUnit测试框架:JUnit测试框架中的TestCase类就是使用了模板方法模式。TestCase类定义了setUp()、tearDown()等模板方法,具体的测试逻辑由子类实现。
    这些是模板方法模式在源码中的一些常见应用。模板方法模式通过定义一个算法的骨架,将具体的实现留给子类来完成。这样可以确保算法的整体结构稳定,同时也提供了灵活性,让子类可以根据需要改变具体的实现。

优缺点

优点:

  1. 提供了一种代码复用的机制:模板方法模式通过定义一个抽象的模板方法和一系列具体的步骤方法,使得多个子类可以共享相同的代码逻辑,提高了代码的复用性。
  2. 定义了算法的骨架:模板方法模式将算法的整体结构定义在抽象类中,具体的步骤由子类实现。这样可以确保算法的结构稳定,同时允许子类根据需要进行具体实现。
  3. 提供了扩展的能力:子类可以通过重写抽象类中的步骤方法来改变算法的具体实现,从而实现对算法的扩展和定制。

缺点:

  1. 可能导致代码膨胀:由于模板方法模式要求定义抽象类和具体的步骤方法,可能会导致类的数量增加,从而增加了代码的复杂性和维护成本。
  2. 可能限制了具体步骤的灵活性:由于算法的整体结构已经在抽象类中定义好,子类只能通过重写具体步骤方法来改变算法的实现,有一定的限制性。

总结

模板方法模式通过定义抽象类和具体的步骤方法,提供了一种代码复用的机制,同时也定义了算法的整体结构。它可以提高代码的复用性和可维护性,但也可能导致代码膨胀和灵活性的限制。在使用模板方法模式时,需要权衡其优缺点,确保合理使用。

更多推荐

LinkedList与链表

目录一、Arraylist的缺陷二、链表2.1链表的概念和结构2.2链表的实现三、链表面试题3.1删除链表中所有值为val的节点3.2反转一个单链表3.3链表的中间节点3.4将有序链表合并3.5输出倒数第k个节点3.6链表分割3.7链表的回文结构3.8找两个链表的公共节点3.9判断链表是否有环3.10找链表入环的第一个

Axure设计之数据图表折线图(中继器)

折线图是一种用于显示数据随时间变化或有序类别关系变化的图形。在折线图中,数据点用线段连接,并按照时间顺序或类别顺序排列。通过观察折线图的走势和变化,可以获得数据变化的趋势和规律。在系统统计分析中折线图经常被使用的数据图表。一、效果展示1、该示例为折线图,分别对客流量和购买量以月份为单位进行统计;2、横轴为统计月份,纵轴

Python经典练习题(一)

文章目录🍀第一题🍀第二题🍀第三题🍀第四题🍀第五题🍀第一题有四个数字:1、2、3、4,能组成多少个互不相同且无重复数字的三位数?各是多少?这里我们使用两种方法进行求解解法一:循环套循环count=0foriinrange(1,5):forjinrange(1,5):forkinrange(1,5):if(i!

如何辨认是否是高防服务器?

因为现在高防服务器比较出名,很多IDC服务器商都标榜自己的服务器是高防服务器,那我们怎么辨别服务器商说的高防服务器是否是真正的高防服务器呢?今天小编就告诉大家几点辨认是否是高防服务器的小要点。向选择好的服务器商要一下高防服务器的IP,然后通过简单的测试来看一看,也就是ping指令(用来测试网络连接是否正常)来检查,一般

如何使用插件扩展Vue的功能

Vue是一款流行的前端JavaScript框架,它的核心库提供了许多强大的功能,但有时我们需要额外的功能来满足特定需求。这时,使用插件来扩展Vue的功能是一个很好的选择。本文将详细介绍如何使用插件来扩展Vue的功能,包括创建、注册和使用插件。Vue提供了强大的插件系统,供大家来扩展项目功能。开发者可以自由的使用公开的第

Python+pytest接口自动化之参数关联

一、什么是参数关联?参数关联,也叫接口关联,即接口之间存在参数的联系或依赖。在完成某一功能业务时,有时需要按顺序请求多个接口,此时在某些接口之间可能会存在关联关系。比如:B接口的某个或某些请求参数是通过调用A接口获取的,即需要先请求A接口,从A接口的返回数据中拿到需要的字段值,在请求B接口时作为请求参数传入。二、有哪些

Hoeffing不等式

在李航老师的统计学习方法(第一版中)Hoeffing不等式Hoeffing不等式Hoeffing不等式是这样子给出的设X1,X2,...,XNX_1,X_2,...,X_NX1​,X2​,...,XN​是独立随机变量,且Xi∈[ai,bi],i=1,2,...,N;SN=∑i=1NXiX_i\in[a_i,b_i],i

VMware Fusion 13在M2芯片的Mac上安装 Windows 11

首先需要下载Windows11镜像以下给出一种官方方法,当然也可以自己去网上搜索,有很多资源注册微软账号使用注册的账号登录访问:https://www.microsoft.com/en-us/windowsinsider/register使用登录的账号注册Windows11InsiderProgram看到以下页面,就是

【2023华为杯A题】WLAN网络信道接入机制建模(代码、思路.....)

💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。⛳️座右铭:行百里者,半于九十。📋📋📋本文目录如下:🎁🎁🎁目录💥1背景1.1分布式信道接入和二进制指数退避1.2基于Markovchain的DCF机制建模和系统性能分析📚2WLAN组

Apache shenyu,Java 微服务网关的首选

微服务网关的产生背景当我们系统复杂度越来越高,团队协作效率越来越低时,我们通常会想到通过"拆分"来应对,这是典型的"化繁为简,分而治之"的思想。在落地过程中,我们通常会引入"SOA"或者"微服务"架构手段,如下图所示:技术更新日新月异,站在当下去看,“微服务”、“API网关”、“云原生”、“servicemesh”…这

CFCA证书 申请 流程(一)

CFCA证书CFCA证书是指由中国金融认证中心颁发的证书,包括普通数字证书、服务器数字证书和预植证书等,目前,各大银行和金融机构都会使用CFCA颁发的证书作为官网的HTTPS证书、手机银行等APP使用的证书以及USB-KEY(U盾)内置的证书。在案例中包括中国工商银行、中国民生银行、中国光大银行、中信银行、兴业银行、中

热文推荐