当前位置: 首页 > article >正文

1.Template Method 模式

模式定义

定义一个操作中的算法的骨架(稳定),而将一些步骤延迟(变化)到子类中。Template Method 使得子类可以不改变(复用)一个算法的结构即可重定义(override 重写)该算法的某些特定步骤。

按目的分类:

创建型(Creational)模式:

  • 将对象的部分创建工作延迟到子类或者其他对象,从而应对需求变化为对象创建时具体类型实现引来的冲击。

结构型(Structural)模式:

  • 通过类继承或者对象组合获得更灵活的结构,从而应对需求变化为对象的结构带来的冲击。

行为型(Behavioral)模式:

  • 通过类继承或者对象组合来划分类与对象间的职责,从而应对需求变化为多个交互的对象带来的冲击。
按范围分类:
  • 类模式处理类与子类的静态关系。
  • 对象模式处理对象间的动态关系。
从封装变化角度对模式分类
组件协作:
  • Template Method
  • Observer/Event
  • Stategy
单一职责:
  • Decorator
  • Bridge
对象创建
  • Factory Method
  • Abstract Factory
  • Prototype
  • Builder
对象性能
  • Sigleton
  • Flyweight
接口隔离
  • Facade
  • Proxy
  • Mediator
  • Adapter
状态变化
  • Memento
  • State
数据结构
  • Composite
  • Iterator
  • Chain of
  • Resposibility
行为变化
  • Command
  • Visitor
领域问题
  • Interpreter

重构获得模式 (Refactoring to Patterns)

  • 面向对象设计模式是 “好的面向对象设计”,指的是可以免租 "应对变化,提高复用"的设计。

  • 现在软件设计的特征是 “需求的频繁变化”。设计模式的要点是 寻找变化点,然后在变化点处应用设计模式,从而更好的应对需求的变化在这里 什么时候、什么地点应用设计模式,比理解设计模式结构代码本身更加重要

  • 设计模式的应用不宜先入为主,一上来就使用设计模式是对设计模式最大的误用。没有一步到位的设计模式。敏捷软件开发实践提倡的 Refactoring to Patterns 是目前普遍公认最好的使用设计模式的方法。

重构关键技法

静态       --> 动态
早绑定     --> 晚绑定
继承       --> 组合
编译时依赖 --> 运行时依赖
紧耦合     --> 松耦合

组件协作模式

现代软件专业分工之后的第一个结果是 “框架与应用程序的划分”,“组件协作” 模式通过晚期绑定,来实现框架与应用程序直接的松耦合,是二者之间协作时常用的模式。

动机(Motivation)

在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但是各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现

如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求。

结构化软件设计流程

例如:当前一个库 有方法:step1,step3,5。那么对应的应用程序需要做步骤step2,step4。然后在使用的时候将这些步骤串起来使用。
结构化软件设计流程
早绑定,这里Library 实现的早,Application调用Library 就是早绑定:
早绑定

需要注意的地方:
virtual ~Library() {} 在C++中基类析构函数需要写成虚函数,如果不写成虚函数,那么可能它不会调用子类的析构函数。

在这里插入图片描述
晚绑定,Library 写的早,但是现在Library 反过来调用Application

晚绑定
变化:


// 库程序开发人员编写
class Library {
public:
    void Step1() {/*...*/ };
	void Step3() {/*...*/ };
	void Step5() {/*...*/ };
};

// 应用程序开发人员编写
class Application {
public:
	void Step2() {/*...*/ };
	void Step4() {/*...*/ };
};


int main()
{
// 当前使用步骤的整体流程
	Library lib;
	Application app;

	lib.Step1();

	if (app.Step2()) {
		lib.Step3();
	}

	for (int i = 0; i < 4; i++) {
		app.Step4();
	}

	lib.Step5();
}

修改上面步骤,让程序库开发人员将框架流程先写下来,让程序开发人员提供的接口 Step2(),Step4()修改为纯虚函数,留给子类重写。

//程序库开发人员
class Library {
public:
	//稳定 template method
	void Run() {

		Step1();

		if (Step2()) { //支持变化 ==> 虚函数的多态调用
			Step3();
		}

		for (int i = 0; i < 4; i++) {
			Step4(); //支持变化 ==> 虚函数的多态调用
		}

		Step5();
	}
	virtual ~Library() {}

protected:

	void Step1() {/*...*/ }
	void Step3() {/*...*/ }
	void Step5() {/*...*/ }

	virtual bool Step2() = 0;//变化
	virtual void Step4() = 0; //变化
};


//应用程序开发人员
class Application : public Library {
protected:
	virtual bool Step2() {
		//... 子类重写实现
	}

	virtual void Step4() {
		//... 子类重写实现
	}
};

int main()
{
	Library* pLib = new Application();
	pLib->Run();

	delete pLib;
} 

Template 的前提是 void Run() 必须稳定,也就是算法的骨架结构可以被重用。

总结

  • Teamplate Method 模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。 它用最简洁的机制(虚函数的多态性)为很多应用程序框架提供了灵活的拓展点,是代码复用方面的基本实现结构

除了可以灵活应对子步骤的变化外,不要调用我,让我来调用你的反向控制结构是 Teamplate Method 的典型应用。

在具体实现方面,被 Template Method 调用的虚方法可以具有 实现,也可以没有任何实现(抽象方法,纯虚方法),但一般推荐将它们设置为 protectecd 方法。


http://www.kler.cn/a/522398.html

相关文章:

  • SSM开发(七) MyBatis解决实体类(model)的字段名和数据库表的列名不一致方法总结(四种方法)
  • 三角形的最大周长(LeetCode 976)
  • 第 5 章:声音与音乐系统
  • 相互作用感知的蛋白-小分子对接模型 - Interformer 评测
  • GO语言 链表(单向链表
  • 【Uniapp-Vue3】StorageSync数据缓存API
  • 【信息系统项目管理师-选择真题】2011下半年综合知识答案和详解
  • 软件测试 —— jmeter(2)
  • SpringBoot中Excel表的导入、导出功能的实现
  • 【处理和预防校园霸凌】。营造安全
  • Android开发基础知识
  • Github 2025-01-26 php开源项目日报Top10
  • 练习题 - Django 4.x File 文件上传使用示例和配置方法
  • 电脑开机后就会出现一个名叫DIRECT-OK***AmsDL的WiFi,***是我的电脑名
  • zyNo.18
  • Golang笔记——常用库context和runtime
  • Linux:线程池和单例模式
  • golang命令大全5--依赖管理
  • 【设计模式-行为型】访问者模式
  • 基于nodejs+json+websocket+html的聊天应用
  • 【unity游戏开发之InputSystem——05】PlayerInput组件的介绍(基于unity6开发介绍)
  • android studio生成jsk
  • 通过visual studio生成与查看汇编代码
  • Spring Web MVC 入门
  • 视频行为分析系统,可做安全行为检测,比如周界入侵,打架
  • LeetCode热题100(七)—— 3.无重复字符的最长子串