行为型模式
学习笔记之C++设计模式——创建型模式
📑 【设计模式】结构型模式
📑 【设计模式】创建型模式
总的来说,行为型模式就是用来对类或对象怎样交互和怎样分配职责进行描述。
模板方法模式
AbstractClass(抽象类):在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法(Template Method),用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。
ConcreteClass(具体子类):它是抽象类的子类,用于是现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中的已经实现的具体基本操作。
模板方法案例
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
#include "stdafx.h" #include <iostream> #include <string> using namespace std;
class Beverage { public: void BoilWater() { cout << "烧开水" << endl; } virtual void Brew() = 0; void PourinVup() { cout << "倒入杯中" << endl; } virtual void AddCondiments() = 0;
virtual bool CustomWantsCondiments() { return true; }
void PrepareBeverage() { BoilWater(); Brew(); PourinVup(); if (CustomWantsCondiments()) { AddCondiments(); } } protected: private: };
class Coffee : public Beverage { public: virtual void Brew() { cout << "冲泡咖啡豆" << endl; } virtual void AddCondiments() { cout << "添加糖和牛奶" << endl; } protected: private: };
class Tea : public Beverage { public: virtual void Brew() { cout << "冲泡茶叶" << endl; } virtual void AddCondiments() { cout << "添加柠檬" << endl; } protected: private: };
int main() { Beverage *pTea = new Tea; pTea->PrepareBeverage(); delete pTea;
cout << "-----------------------" << endl;
Beverage *pCoffee = new Tea; pCoffee->PrepareBeverage(); delete pCoffee;
return 0; }
|
输出:
烧开水
冲泡茶叶
倒入杯中
添加柠檬
-----------------------
烧开水
冲泡茶叶
倒入杯中
添加柠檬
请按任意键继续. . .
## 模板方法的优缺点
- 在父类中形式化地定义一个算法,而由它的子类来实现细节的处理,在子类实现详细的处理算法时并不会改变算法中步骤的执行次序。
- 模板方法模式是一种代码复用技术,它在类库设计中尤为重要,它提取了类库中的公共行为,将公共行为放在父类中,而通过其子类来实现不同的行为,它鼓励我们恰当使用继承来实现代码复用。
- 可实现一种反向控制结构,通过子类覆盖父类的钩子方法来决定某一特定步骤是否需要执行。
- 在模板方法模式中可以通过子类来覆盖父类的基本方法,不同的子类可以提供基本方法的不同实现,更换和增加新的子类很方便,符合单一职责原则和开闭原则
需要为每一个基本方法的不同实现提供一个子类,如果父类中可变的基本方法太多,将会导致类的个数增加,系统更加庞大,设计也更加抽象。
适用场景
-
具有统一的操作步骤或操作过程;
-
具有不同的操作细节;
-
存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同
在抽象类中统一操作步骤,并规定好接口;让子类实现接口。这样可以吧各个具体的子类和操作步骤解耦合。
命令模式
将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为模式,其别名为动作(Action)模式或事务(Tranaction)模式。
命令模式可以将请求发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
#include "stdafx.h" #include <iostream> using namespace std;
class Doctor { public: void treat_eye() { cout << "医生 治疗 眼科病" << endl; } void treat_nose() { cout << "医生 治疗 鼻科病" << endl; } protected: private: };
class CommandTreatEye { public: CommandTreatEye(Doctor *doctor) { m_doctor = doctor; }
void treat() { m_doctor->treat_eye(); } private: Doctor *m_doctor; };
class CommandTreatNose { public: CommandTreatNose(Doctor *doctor) { m_doctor = doctor; }
void treat() { m_doctor->treat_nose(); } private: Doctor *m_doctor; };
int main() { Doctor *doctor = new Doctor; doctor->treat_eye(); delete doctor;
cout << "-----------------" << endl;
Doctor *doctorCmd = new Doctor; CommandTreatEye * cmdEyeDoc = new CommandTreatEye(doctorCmd); cmdEyeDoc->treat(); delete cmdEyeDoc; CommandTreatNose *cmdNoseDoc = new CommandTreatNose(doctorCmd); cmdNoseDoc->treat(); delete cmdNoseDoc;
delete doctorCmd;
return 0; }
|
输出:
医生 治疗 眼科病
-----------------
医生 治疗 眼科病
医生 治疗 鼻科病
请按任意键继续. . .
> 命令模式的本质是对请求进行封装对应于一个命令,将发出命令的责任和执行命令的责任分割开。
命令模式中的角色和职责
策略模式
观察者模式