5.设计模式之模板方法

news/2024/10/18 6:13:42/

前言

模板方法模式是软件开发中经常用得到模式。在很多流行的框架中都能看到他的身影。比如spring,junit,servlet等等。它定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现

这样,新的子类可以在不改变一个算法结构的前提下重新定义该算法的某些特定步骤。本节,我们就模板方法展开详细介绍。

我们以请客吃饭为例,在我们请客吃饭中,通用的有三步,点菜,吃饭,买单。这三步是固定的,但是具体到每次请客,点的菜是不确定的,为此,我们可以将不固定的细节交给子类自己决定,不变的内容放到父类。代码示例如下

1. 定义抽象父类

package com.wanlong.design_pattern.action.templeteMethod;/*** @author wanlong* @version 1.0* @description: 抽象父类,定义不变的结构* @date 2022/9/20 14:34*/
public abstract class AbstractTemplete {void invite(){//点菜order();//吃饭,不同人口味不同,抽象出来,子类实现eat();//聊天chat();//买单pay();}void order(){System.out.println("开始点菜");}void pay(){System.out.println("吃完付款");}void chat(){}//子类实现 abstract void eat();
}

2. 定义子类

2.1 定义子类客户1

package com.wanlong.design_pattern.action.templeteMethod;/*** @author wanlong* @version 1.0* @description:* @date 2022/9/20 14:39*/
public class Guest1 extends AbstractTemplete{@Overridevoid eat() {System.out.println("四川人喜欢吃辣,口味偏辣");}
}

2.2 定义子类客户2

package com.wanlong.design_pattern.action.templeteMethod;/*** @author wanlong* @version 1.0* @description:* @date 2022/9/20 14:39*/
public class Guest2 extends AbstractTemplete{@Overridevoid eat() {System.out.println("甘肃人喜欢吃面,来碗牛肉面");}
}

3. 测试调用

3.1 测试demo

@Test
public void testTEmplete() {AbstractTemplete guest1 = new Guest1();AbstractTemplete guest2 = new Guest2();guest1.invite();System.out.println("==========");guest2.invite();
}

3.2 结果

开始点菜
四川人喜欢吃辣,口味偏辣
吃完付款
==========
开始点菜
甘肃人喜欢吃面,来碗兰州拉面
吃完付款

4. 总结

模板方法,因为java继承的特性原因,在我们实际开发中,是用的比较多的设计模式。但是这特别考验开发的抽象能力。开发需要将所有子类通用的步骤,功能抽象到父类,形成通用的模板方法,然后可变的内容实现交给子类自己实现管理

模板方法模式主要是用来解决复用扩展两个问题。

模板方法模式把**一个算法中不变的流程抽象到父类的模板方法TemplateMethod()**中,将可变的部分留给子类ConcreteClassA和ConcreteClassB来实现,所有的子类都可以复用父类中模板方法定义的流程代码

模板方法模式的第二大作用是扩展,这里所说的扩展,并不是指代码的扩展性,而是指框架的扩展性。基于这个作用,模板方法模式常用在框架的开发中,让框架用户可以在不修改框架源码的情况下,定制化框架的功能

4.1 优缺点

4.1.1 优点

  1. 封装不变部分,扩展可变部分,把认为是不变部分的算法封装到父类实现,而可变部分的则可以通过继承来继续扩展。
  2. 提取公共部分代码,便于维护
  3. 行为由父类控制,子类实现。基本方法是由子类实现的,因此子类可以通过扩展的方式增加相应的功能,符合开-闭原则。

4.1.2 缺点

  1. 每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,间接地增加了系统实现的复杂度。
  2. 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它降低了代码的可阅读性。
  3. 由于继承关系自身的缺点,如果父类添加新的抽象方法,则所有子类都要改一遍

4.2 模板方法模式的应用场景

  1. 算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。

  2. 当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。首先,要识别现有代码中的不同之处,并且将不同之处分离为新的操作,最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。

  3. 需要控制子类的扩展时,模板方法只在特定点调用钩子操作,这样只允许在这些点进行扩展。在很多框架中可以看到这种使用方式,比如spring

4.3 框架中的体现

  1. 数据库访问的封装
  2. Junit单元测试
  3. servlet中关于doGet/doPost方法调用
  4. Hibernate中模板程序
  5. spring中JDBCTemplate、HibernateTemplate等。

以上,本人菜鸟一枚,如有问题,请不吝指正。


http://www.ppmy.cn/news/64555.html

相关文章

操作系统基础知识介绍之可靠性与可用性(包含MTTF、MRBF、MTTR等)

计算机是在不同的抽象层上设计和构建的。 我们可以通过计算机递归地下降,看到组件将自身放大为完整的子系统,直到我们遇到单个晶体管。 尽管有些故障很普遍,例如断电,但许多故障仅限于模块中的单个组件。 因此,一个模块…

Java框架学习04(SpringBoot自动装配原理)

1、什么是 SpringBoot 自动装配? 2、SpringBoot 是如何实现自动装配的?如何实现按需加载? 3、如何实现一个 Starter? 前言 使用过 Spring 的小伙伴,一定有被 XML 配置统治的恐惧。即使 Spring 后面引入了基于注解的配…

【 断电延时继电器 电源监视 导轨安装 JOSEF约瑟 HJZS-E202 AC220V】

品牌:JOSEF约瑟型号:HJZS-E202名称:断电延时继电器额定电压:110、220VDC/AC;100VAC触点容量:250V/5A功率消耗:≤4.2W返回系数:10%额定电压 系列型号: HJZS-E202断电延时…

女子拍视频宣传家乡因高颜值走红 网友:是心动的感觉

近日,一位90后女子李巧因其高颜值在网上走红,引起了广泛的关注。 有网友认为她是新疆旅游协会秘书长,但她的助理郑先生称,李巧并非如此,而是一位民宿文旅行业达人。 据郑先生介绍,李巧曾走遍全中国&#xf…

手术麻醉系统源码——业务流程介绍

采用计算机和通信技术,实现监护仪、麻醉机、呼吸机、输液泵等设备输出数据的自动采集,采集的数据能够如实准确地反映患者生命体征参数的变化,并实现信息高度共享,根据采集结果,综合其他患者数据,自动生成手…

Transformer结构细节

一、结构 Transformer 从大的看由 编码器输入、编码器、解码器、解码器输入和解码器输出构成。 编码器中包含了词嵌入信息编码、位置编码、多头注意力、Add&Norm层以及一个全连接层; 解码器中比编码器多了掩码的多头注意力层。 二、模块 2.1 Input Embeddi…

TypeScript:为什么JavaScript需要类型检查?

JavaScript是当今最为流行的编程语言之一。它是一种高级的、解释性的编程语言,用于Web应用程序的开发。然而,JavaScript的灵活性也是它的弱点之一。JavaScript中的变量、函数、类等都是动态类型,这意味着它们的类型可以在运行时发生变化。虽然…

从Pandas快速切换到Polars :数据的ETL和查询

对于我们日常的数据清理、预处理和分析方面的大多数任务,Pandas已经绰绰有余。但是当数据量变得非常大时,它的性能开始下降。 我们以前的两篇文章来测试Pandas 1.5.3、polar和Pandas 2.0.0之间的性能了,Polars 正好可以解决大数据量是处理的…