23种设计模式(三)——模板方法模式【组件协作】

news2024/11/17 12:26:37

文章目录

    • 意图
    • 什么时候使用模板方法
      • 真实世界类比
    • 常说的钩子
    • 模板方法的实现
    • 模板方法模式的优缺点

亦称: Template Method

意图

它的主要思想是,定义一个操作的一系列步骤,对于某些暂时确定不下来的步骤,就留给子类去实现好了,这样不同的子类就可以定义出不同的步骤。因此,模板方法的核心在于定义一个“骨架”。模板方法模式很好的体现了好莱坞原则(Hollywood Principle): Don’t call us, we’ll call you。使得父类来控制程序流程,父类根据程序执行需要将子类的功能勾到父类中,程序流程倒置这个点需要花一点时间适应。

在这里插入图片描述

什么时候使用模板方法

  1. 算法的整体步骤很固定,但是其中一些方法需要根据场景不同,进行不同的实现,我们就可以将易变的抽象出来,交由子类实现。
  2. 当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。
  3. 当需要控制子类的扩展部分是否执行时,可以在特定的方法前调用钩子操作,这样就增强了模板方法的灵活性。

真实世界类比

在这里插入图片描述

可对典型的建筑方案进行微调以更好地满足客户需求。

模板方法可用于建造大量房屋。 标准房屋建造方案中可提供几个扩展点, 允许潜在房屋业主调整成品房屋的部分细节。

每个建造步骤 (例如打地基、 建造框架、 建造墙壁和安装水电管线等) 都能进行微调, 这使得成品房屋会略有不同。

常说的钩子

钩子 相信大家曾经有听到过,但是可能一直不太理解,它是一种被声明在抽象类中的方法,但只有空的或者默认的实现。 钩子的存在,可以让子类有能力对算法的不同点进行挂钩。要不要挂钩由子类自行决定。

它和模板方法是搭配着使用的,假设现在要加入一个新的方法调用,改变了模板方法。但是这个方法又不是所有的子类都需要实现,希望将这个选择的能力交给子类选择,就可以将这个方法在超类中定义为空方法或者默认实现,子类可以选择覆盖,但不一定非要这么做,这就是钩子的作用。

模板方法的实现

1、抽象类 (Abstract­Class) 会声明作为算法步骤的方法, 以及依次调用它们的实际模板方法。 算法步骤可以被声明为 抽象类型, 也可以提供一些默认实现。

2、具体类 (Concrete­Class) 可以重写所有步骤, 但不能重写模板方法自身。

class AbstractClass 
{
	/**
	 * The template method defines the skeleton of an algorithm.
	 */
public:
	void TemplateMethod() const {
		this->BaseOperation1();
		this->RequiredOperations1();
		this->BaseOperation2();
		this->Hook1();
		this->RequiredOperation2();
		this->BaseOperation3();
		this->Hook2();
	}
	/**
	 * These operations already have implementations.
	 */
protected:
	void BaseOperation1() const {
		std::cout << "AbstractClass says: I am doing the bulk of the work\n";
	}
	void BaseOperation2() const {
		std::cout << "AbstractClass says: But I let subclasses override some operations\n";
	}
	void BaseOperation3() const {
		std::cout << "AbstractClass says: But I am doing the bulk of the work anyway\n";
	}
	/**
	 * These operations have to be implemented in subclasses.
	 */
	virtual void RequiredOperations1() const = 0;
	virtual void RequiredOperation2() const = 0;
	/**
	 * These are "hooks." Subclasses may override them, but it's not mandatory
	 * since the hooks already have default (but empty) implementation. Hooks
	 * provide additional extension points in some crucial places of the
	 * algorithm.
	 */
	virtual void Hook1() const {}
	virtual void Hook2() const {}
};
/**
 * Concrete classes have to implement all abstract operations of the base class.
 * They can also override some operations with a default implementation.
 */
class ConcreteClass1 : public AbstractClass 
{
protected:
	void RequiredOperations1() const override {
		std::cout << "ConcreteClass1 says: Implemented Operation1\n";
	}
	void RequiredOperation2() const override {
		std::cout << "ConcreteClass1 says: Implemented Operation2\n";
	}
};
/**
 * Usually, concrete classes override only a fraction of base class' operations.
 */
class ConcreteClass2 : public AbstractClass 
{
protected:
	void RequiredOperations1() const override {
		std::cout << "ConcreteClass2 says: Implemented Operation1\n";
	}
	void RequiredOperation2() const override {
		std::cout << "ConcreteClass2 says: Implemented Operation2\n";
	}
	void Hook1() const override {
		std::cout << "ConcreteClass2 says: Overridden Hook1\n";
	}
};

模板方法模式的优缺点

优点缺点
很好的符合的“开闭原则”部分客户端可能会受到算法框架的限制
提高了代码的复用度通过子类抑制默认步骤实现可能会导致违反_里氏替换原则
模板方法中的步骤越多, 其维护工作就可能会越困难

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/160399.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

位图与矢量图的区别

相信大家在日常的工作过程中&#xff0c;经常会听到位图和矢量图&#xff0c;那么位图和矢量图的区别是什么呢&#xff1f; 1.定义 ①位图&#xff1a;称为点阵图像或栅格图像&#xff0c;是由称作像素&#xff08;图片元素&#xff09;的单个点组成的。这 些点可以进行不同的排…

测试用例设计方法有哪些?举例说明

众所周知&#xff0c;测试用例是编制的一组测试输入、执行条件及预期结果&#xff0c;专门为的是某个特殊目标&#xff0c;即测试某个程序路径&#xff0c;或是核实是否满足某个特定的需求。一般来讲&#xff0c;常用的测试用例设计方法有五种&#xff0c;分别是&#xff1a;正…

微信小程序中如何实现双向绑定

一、双向绑定 在微信小程序中如何实现双向绑定&#xff1f;在开始之前先介绍下什么是双向绑定&#xff0c;js中定义变量数据后&#xff0c;通过{{}}绑定到模板中&#xff0c;这个过程是单向绑定&#xff0c;即数据的更新只能是js中更新了数据&#xff0c;模板中跟着修改。但是如…

深度学习笔记:神经网络(3)

关于本章之前内容可以参考以下之前文章&#xff1a; 1 https://blog.csdn.net/Raine_Yang/article/details/128473486?spm1001.2014.3001.5501 2 https://blog.csdn.net/Raine_Yang/article/details/128584916?spm1001.2014.3001.5501 神经网络的输出层设计 机器学习问题一般…

2022年12月青少年软件编程(Python) 等级考试试卷(三级)

2022. 12 青少年软件编程&#xff08;Python&#xff09; 等级考试试卷&#xff08;三级&#xff09; 一、 单选题(共 25 题&#xff0c; 共 50 分) 1.列表 L1 中全是整数&#xff0c; 小明想将其中所有奇数都增加 1&#xff0c; 偶数不变&#xff0c; 于是编写了如下图 所示的…

高级树结构之平衡二叉树(ALV树)

文章目录平衡二叉树简介失衡类型&处理办法RR型失衡【左旋调整】调整演示代码实现LL型失衡【右旋调整】调整演示代码实现RL型失衡【先右旋后左旋调整】调整演示代码实现LR型失衡【先右旋后左旋调整】调整演示代码实现插入操作综合代码演示平衡二叉树简介 在数据有序的情况下…

Codeforces Round #842 (Div. 2)

Codeforces Round #843 (Div. 2) 传送门 不想搞的很累&#xff0c;对自己不做要求&#xff0c;有兴趣就做。 A. Greatest Convex #include <bits/stdc.h>using namespace std; const int maxn 1e6 10; vector<int> cnt[maxn]; map<int, int> mp;int mai…

nvm安装 疑难问题解决

nvm介绍 NVM是node.js的版本管理器&#xff0c;设计为每个用户安装&#xff0c;并在每个shell中调用。nvm可以在任何兼容posix的shell (sh、dash、ksh、zsh、bash)上运行&#xff0c;特别是在这些平台上:unix、macOS和windows WSL。 nvm安装 &#xff01;&#xff01;重要&a…

强化学习在智能补货场景的应用

本文作者&#xff1a;应如是&#xff0c;观远算法团队工程师&#xff0c;毕业于伦敦帝国理工学院计算机系&#xff0c;主要研究方向为强化学习、时间序列算法及其落地应用。深耕零售消费品场景&#xff0c;解决供应链运筹优化问题。为客户提供基于机器学习的AI解决方案。1. 背景…

2023.Q1 go语言记录

1. Go 语言数组声明和初始化var variable_name [SIZE] variable_type&#xff0c;eg&#xff1a;var balance [10] float32var balance [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}balance : [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}长度不确定的初始化var balance [...]float…

少儿Python每日一题(21):八皇后问题

原题解答 本次的题目如下所示: 会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即,…

【Ansible】Ansible Playbook 的任务控制

Ansible Playbook 的任务控制 文章目录Ansible Playbook 的任务控制一、Ansible 任务控制基本介绍二、条件判断1.解决第一个问题2.nginx 语法校验三、循环控制四、Tags 属性五、Handlers 属性一、Ansible 任务控制基本介绍 任务控制类似于编程语言中的 if …、for …等逻辑控制…

MSF社会工程学

● Metasploit发现两个远程代码执行漏洞 ○ 问题都出在WEB组件方面 ○ MSF不受影响 ● 安全面前任何软件都是平等的 ○ 没有绝对安全的软件 为什么要说社会工程学 ● Metasploit可以很好的配合到社会工程学攻击的各个阶段 ● Setoolkit工具包大量依赖Metasploit ● 基于浏览器…

[SUCTF 2019]EasySQL

目录 预先知识 信息收集 思路 源码分析 非预期解 预期解 补充 预先知识 环境 use mysql; create table if not exists my_table( id int PRIMARY key auto_increment, name VARCHAR(20), age int); insert into my_table values(NULL,xiao,19); insert into my_table v…

BUFF80双模蓝牙5.2热插拔PCB

键盘使用说明索引&#xff08;均为出厂默认值&#xff09;软件支持一些常见问题解答&#xff08;FAQ&#xff09;首次使用测试步骤蓝牙配对规则&#xff08;重要&#xff09;蓝牙和USB切换键盘默认层默认触发层0的FN键配置的功能默认功能层1配置的功能默认的快捷键蓝牙参数蓝牙…

Jetpack Compose中的Canvas

Jetpack Compose中的Canvas API 使用起来感觉比传统View中的要简单一些&#xff0c;因为它不需要画笔Paint和画布分开来&#xff0c;大多数直接就是一个函数搞定&#xff0c;当然也有一些限制。 Compose 直接提供了一个叫 Canvas 的 Composable 组件&#xff0c;可以在任何 Co…

containerd环境下build镜像

containerd环境下build镜像安装nerdctl使用nerdctl打包docker镜像下载安装 buildkit编写systemd unit文件&#xff1a;启用buildkit.service并设置开机自动运行修改Dockerfile构建镜像containerd配置代理containerd配置代理ansible剧本安装nerdctl https://blog.csdn.net/omai…

Python采集最热影评 + 制作词云图

人生苦短&#xff0c;我用Python 电影评论&#xff0c;简称影评 是对一部电影的导演、演员、镜头、摄影、剧情、线索、环境、色彩、光线、视听语言、道具作用、转场、剪辑等进行分析和评论。 电影评论的目的在于分析、鉴定和评价蕴含在银幕中的审美价值、认识价值、社会意义、…

Springboot中,异步线程的执行顺序的控制

1、顺序的定义异步任务存在如下几种顺序&#xff1a;顺序的开启子任务&#xff08;运行顺序和结束顺序不确定&#xff09;。顺序的完成&#xff08;就是A先启动&#xff0c;先执行完&#xff0c;再执行B任务&#xff0c;往往A、B之间存在某种依赖关系&#xff09;。还有就是优先…

思科设备-配置静态路由

⬜⬜⬜ &#x1f430;&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; (*^▽^*)欢迎光临 &#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;&#x1f430;⬜⬜⬜ ✏️write in front✏️ &#x1f4dd;个人主页&#xff1a;陈丹宇jmu &a…