模板方法设计模式

ops/2024/10/18 20:09:51/

阅读本文之前,请投票支持这款 全新设计的脚手架 ,让 Java 再次伟大!

模板方法设计模式怎么用?

试想一个业务场景。项目产生了一个代码排序后打印的需求。此需求被交付给了程序员 A 来实现。A 通过分析需求后发现要解决此问题需要 2 个步骤.

  1. 排序数组
  2. 打印排序后的数组

打印好做,而排序方法和规则较多,就比较麻烦了。于是 A 想到了一个办法,先把打印部分的代码做好,其他的交由其他程序员实现。

java">/*** 模板方法设计模式* 抽象类*/
public abstract class AbstractSort {/*** 将数组由大到小排序.** @param array*/protected abstract void sort(int[] array);/*** 打印排序好的数组.** @param array*/public final void showSortResult(int[] array) {this.sort(array);System.out.print("排序结果:");for (int i = 0; i < array.length; i++) {System.out.printf("%3s", array[i]);}}}

现在,A 已经做好了该需求主要框架部分的代码了。于是 A 通知到程序员 B,希望由 B 来负责实现剩下的逻辑。

java">/*** 模板方法设计模式* 排序具体实现类*/
public class ConcreteSort extends AbstractSort {/*** 排序方法* 排序数组里每个元素的值.** @param array 数组*/@Overrideprotected void sort(int[] array) {for (int i = 0; i < array.length - 1; i++) {selectSort(array, i);}}/*** 排序具体算法实现* 遍历每个元素,找出相对于当前最小的元素的索引,然后调换互相的位置** @param array 数组* @param index 索引*/private void selectSort(int[] array, int index) {int MinValue = 32767; // 最小值变量int indexMin = 0; // 最小值索引变量int Temp; // 暂存变量for (int i = index; i < array.length; i++) {if (array[i] < MinValue) { // 找到最小值MinValue = array[i]; // 储存最小值indexMin = i;}}Temp = array[index]; // 交换两数值array[index] = array[indexMin];array[indexMin] = Temp;}}

程序员 B 实现了小->大的排序逻辑,通知到 A 进行测试。

java">
/*** 模板方法设计模式* 排序测试*/
public class Client {public static int[] a = {10, 32, 1}; // 预设数据数组public static void main(String[] args) {AbstractSort s = new ConcreteSort();s.showSortResult(a);}
}

排序结果: 1,10,32
这就是模板方法模式的主要用法。是不是很好理解?认识了模板方法的用法以后,再认识一下模板方法模式的结构,从理论上巩固一下该章节的知识。

模板方法模式主要包含下面 3 个方法。

  • 模板方法
  • 抽象方法
  • 钩子方法

模板方法
父类中只声明但不加以实现,而是定义好规范,然后由它的子类去实现。

抽象方法
由抽象类声明并加以实现。一般来说,模版方法调用抽象方法来完成主要的逻辑功能,并且,模版方法大多会定义为 final 类型,指明主要的逻辑功能在子类中不能被重写。

钩子方法
由抽象类声明并加以实现。但是子类可以去扩展,子类可以通过扩展钩子方法来影响模版方法的逻辑。
抽象类的任务是搭建逻辑的框架,通常由经验丰富的人员编写,因为抽象类的好坏直接决定了程序是否稳定性。实现类用来实现细节。抽象类中的模版方法正是通过实现类扩展的方法来完成业务逻辑。只要实现类中的扩展方法通过了单元测试,在模版方法正确的前提下,整体功能一般不会出现大的错误。

总结

  1. 模板方法模式在项目中会经常运用到,需要熟练掌握。
  2. 模板方法模式结构清晰。一般在项目中常常将不易于变化的部分封装为模板方法。而将易于变化的部分定义为抽象方法。
  3. 模板方法模式易于扩展。面对新增需求,只需要增加相应的模板抽象方法实现子类就可以了,符合了接口的开闭原则。
  4. 在多个子类拥有相同的方法,并且这些方法逻辑相同时,可以考虑使用模版方法模式。在程序的主框架相同,细节不同的场合下,也比较适合使用这种模式。

http://www.ppmy.cn/ops/126550.html

相关文章

怎么把一段音频的人声和背景音乐分开?

在数字音频处理中&#xff0c;将一段音频中的人声和背景音乐分开是一个复杂但又常见的需求。这种技术广泛应用于音乐制作、影视后期、广告制作等多个领域。本文将为你详细解析如何通过不同的方法实现这一目标&#xff0c;帮助你更好地掌握音频分离技术。 一、音频分离的基本概念…

Docker镜像的使用

目录 前提条件 Docker命令图 镜像命令的使用 列出镜像列表 搜索镜像 拉取镜像 查看镜像占用存储空间 删除镜像 制作镜像 从已经创建容器的创建镜像 从Dockerfile中构建镜像 保存与加载镜像 发布镜像 1.命名空间和镜像仓库准备 2.登录阿里云Docker Registry 3.给…

md语法总结

粗体_/* 正常用法 **粗体** __粗体__ 异常用法 *空格具体内容 段落 ** 空格粗体 ** 不渲染 __ 空格粗体 __ 不渲染 *_粗_* 斜体 _*粗*_ 斜体 *斜 不渲染 _斜体 不渲染斜体_/* 正常用法 __斜体__ **斜体** 异常用法 同粗体异常用法粗斜体 正常用法 ***粗斜体*** ___粗斜体___ 异…

Vue3 props

组件与组件之间不是完全独立的&#xff0c;而是有交集的&#xff0c;组件与组件之间可以传递数据&#xff0c;通过props属性可以让子组件接收父组件传递过来的数据。 以父组件-App.vue&#xff0c;子组件-Person.vue为例&#xff1a; 将子组件当作HTML中的标签一样&#xff0c…

Unity3D 物体表面水滴效果详解

在游戏开发中&#xff0c;逼真的水滴效果能够显著提升游戏场景的真实感和沉浸感。Unity3D作为一款强大的游戏开发引擎&#xff0c;提供了丰富的工具和技术来实现这种效果。本文将详细介绍如何在Unity3D中实现物体表面的水滴效果&#xff0c;包括技术详解和代码实现。 对惹&…

Android iOS 使用 ARMS 用户体验监控(RUM)的最佳实践

作者&#xff1a;元泊 引言 背景信息 随着移动互联网技术的持续演进与全民互联网时代的深入&#xff0c;用户在 Android、iOS 应用程序、小程序、H5 游戏及网页等多元化平台上的交互时长显著增长。这一趋势加剧了用户体验&#xff08;UX&#xff09;场景的复杂性&#xff0c…

20201017-【C、C++】跳动的爱心

效果图片 代码 #include "graphics.h" #include <conio.h> #include <time.h> #include <math.h> #include <stdlib.h>struct Point {double x, y;COLORREF color; };COLORREF colors[256] {RGB(255,32,83),RGB(252,222,250),RGB(255,0,0)…

vue3之生命周期钩子

Vue 组件实例生命周期 每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤&#xff0c;比如设置好数据侦听&#xff0c;编译模板&#xff0c;挂载实例到 DOM&#xff0c;以及在数据改变时更新 DOM。在此过程中&#xff0c;它也会运行被称为生命周期钩子的函数&#xff0c…