行为型模式
用来对类或对象怎样交互和怎样分配职责进行描述
模板方法模式
定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
#include <iostream> using namespace std; //模板方法模式 class DrinkTemplate { public: virtual void BoilWater() = 0; virtual void Brew() = 0; virtual void Pour() = 0; virtual void AddSomething() = 0; //模板方法 void Make() { BoilWater(); Brew(); Pour(); AddSomething(); } }; //冲泡咖啡 class Coffee : public DrinkTemplate { virtual void BoilWater() { cout << "煮矿泉水" << endl; } virtual void Brew() { cout << "冲泡咖啡" << endl; } virtual void Pour() { cout << "把咖啡倒入杯中" << endl; } virtual void AddSomething() { cout << "加点糖 加点牛奶" << endl; } }; //冲泡茶水 class Tea : public DrinkTemplate { virtual void BoilWater() { cout << "煮自来水" << endl; } virtual void Brew() { cout << "冲泡西湖龙井" << endl; } virtual void Pour() { cout << "把茶水倒入杯中" << endl; } virtual void AddSomething() { cout << "加柠檬" << endl; } }; void test01() { DrinkTemplate* tea = new Tea; tea->Make(); delete tea; cout << "-------------------" << endl; tea = new Coffee; tea->Make(); } int main() { test01(); }
输出结果:
煮自来水
冲泡西湖龙井
把茶水倒入杯中
加柠檬
-------------------
煮矿泉水
冲泡咖啡
把咖啡倒入杯中
加点糖 加点牛奶
总结:这种模式应用在类之间的操作步骤一致 但是细节不一样。 父类定义框架,子类实现细节,子类的实现并不会影响父类的步骤执行次序,模板方法时一种代码复用技术,在类库设计中尤为重要,这种模式下增加一个子类非常方便,符合单一职责和开闭原则
策略模式
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
案例:
#include <iostream>
using namespace std;
//策略模式
//抽象武器
class WeaponStrategy {
public:
virtual void UseWeapon() = 0;
};
//刀
class Knife : public WeaponStrategy {
virtual void UseWeapon() {
cout << "使用匕首" << endl;
}
};
//AK47
class AK47 : public WeaponStrategy {
virtual void UseWeapon() {
cout << "使用AK47" << endl;
}
};
//角色
class Character {
public:
void setWeapon(WeaponStrategy* pWeapon) {
this->pWeapon = pWeapon;
}
void AttackWeapon() {
this->pWeapon->UseWeapon();
}
public:
WeaponStrategy* pWeapon;
};
void test01() {
//创建角色
Character* character = new Character;
//武器策略
WeaponStrategy* knife = new Knife;
WeaponStrategy* ak47 = new AK47;
//角色类调用setWeapon成员函数 并传入knife对象
character->setWeapon(knife);
character->AttackWeapon();
character->setWeapon(ak47);
character->AttackWeapon();
delete ak47;
delete knife;
delete character;
}
int main() {
test01();
//输出结果:使用匕首
// 使用AK47
}
总结:这个案例非常的简单 定义一个武器抽象父类 子类实现了刀和枪。 再定义一个角色类 内部维护了一个武器抽象类变量 两者属于关联关系 把这个抽象类变量作为参数可以传入不同的武器 实现了多态:一个接口多种实现
命令模式
将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销操作。命令模式时一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。
命令模式可以将请求发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。
#include <iostream>
using namespace std;
#include <queue>
#include <Windows.h>
//命令模式
//协议处理类
class HandleClientProtocol {
public:
//处理增加金币
void AddMoney() {
cout << "给玩家增加金币" << endl;
}
//处理增加钻石
void AddDiamond() {
cout << "给玩家增加钻石" << endl;
}
//处理玩家装备
void AddEquipment() {
cout << "给玩家穿装备" << endl;
}
//处理玩家升级
void AddLevel() {
cout << "给玩家升级" << endl;
}
};
//协议命令接口
class AbstractCommand {
public:
virtual void handle() = 0; //处理客户端请求的接口
};
//处理增加金币请求
class AddMoneyCommand : public AbstractCommand {
public:
AddMoneyCommand(HandleClientProtocol* protocol) {
this->protocol = protocol;
}
virtual void handle() {
this->protocol->AddMoney();
}
public:
HandleClientProtocol* protocol;
};
//处理增加钻石请求
class AddDiamondCommand : public AbstractCommand {
public:
AddDiamondCommand(HandleClientProtocol* protocol) {
this->protocol = protocol;
}
virtual void handle() {
this->protocol->AddDiamond();
}
public:
HandleClientProtocol* protocol;
};
//处理玩家装备请求
class AddEquipmentCommand : public AbstractCommand {
public:
AddEquipmentCommand(HandleClientProtocol* protocol) {
this->protocol = protocol;
}
virtual void handle() {
this->protocol->AddEquipment();
}
public:
HandleClientProtocol* protocol;
};
//处理玩家升级请求
class AddLevelCommand : public AbstractCommand {
public:
AddLevelCommand(HandleClientProtocol* protocol) {
this->protocol = protocol;
}
virtual void handle() {
this->protocol->AddLevel();
}
public:
HandleClientProtocol* protocol;
};
//服务器类
class Server {
public:
void addRequest(AbstractCommand* command) {
mCommand.push(command);
}
void startHandle() {
while (!mCommand.empty()) {
//模拟一下 两秒钟处理一个协议
Sleep(2000);
AbstractCommand* command = mCommand.front();
command->handle();
mCommand.pop();
}
}
public:
queue<AbstractCommand*> mCommand;
};
void test01() {
HandleClientProtocol* protocol = new HandleClientProtocol;
//客户端增加金币的请求
AbstractCommand* addmoney = new AddMoneyCommand(protocol);
//客户端增加钻石的请求
AbstractCommand* adddiamond = new AddDiamondCommand(protocol);
//客户端穿装备的请求
AbstractCommand* addequipment = new AddEquipmentCommand(protocol);
//客户端升级的请求
AbstractCommand* addlevel = new AddLevelCommand(protocol);
Server* server = new Server;
//将客户端的请求加入到队列中
server->addRequest(addmoney);
server->addRequest(adddiamond);
server->addRequest(addequipment);
server->addRequest(addlevel);
//服务器开始处理请求
server->startHandle();
}
int main() {
test01();
}
总结:其实这个命令模式在真实开发中因具体需求的不同可以有很多种形式 不一定是绝对按照上面的形式 但是其核心是得有一个抽象父类和一些子类实现 并把父类类型的队列作为Server的成员变量 然后实现的子类放入队列中按照一定顺序执行
观察者模式
随着交通信号灯的变化,汽车的行为也将随之而变化,一盏交通信号灯可以指挥多辆汽车。
观察者模式是用于建立一种对象与对象之间的依赖关系,一个对象发生变化时将自动通知其他对象,其他对象将相应做出反应。在观察者模式中,发生变化的对象称为观察目标,而被通知的对象称为观察者,一个观察者目标可以对应多个观察者。
#include <iostream>
using namespace std;
#include <list>
//观察者模式
//抽象英雄 : 观察者
class AbstractHero {
public:
virtual void Update() = 0;
};
//英雄A
class HeroA : public AbstractHero {
public:
HeroA() {
cout << "英雄A正在打BOSS" << endl;
}
virtual void Update() {
cout << "英雄A停止 待机状态" << endl;
}
};
//英雄B
class HeroB :public AbstractHero {
public:
HeroB() {
cout << "英雄B在打BOSS" << endl;
}
virtual void Update() {
cout << "英雄B停止 待机状态" << endl;
}
};
//英雄C
class HeroC :public AbstractHero {
public:
HeroC() {
cout << "英雄C在打BOSS" << endl;
}
virtual void Update() {
cout << "英雄C停止 待机状态" << endl;
}
};
//抽象观察目标
class AbstractBoss {
public:
//添加观察者
virtual void addHero(AbstractHero* hero) = 0;
//删除观察者
virtual void deleteHero(AbstractHero* hero) = 0;
//通知所有观察者
virtual void notify() = 0;
};
//具体的观察目标
class BossA : public AbstractBoss {
public:
virtual void addHero(AbstractHero* hero) {
heroList.push_back(hero);
}
virtual void deleteHero(AbstractHero* hero) {
heroList.remove(hero);
}
virtual void notify() {
for (list<AbstractHero*>::iterator it = heroList.begin(); it != heroList.end();it++) {
(*it)->Update();
}
}
public:
list<AbstractHero*> heroList;
};
void test01() {
//创建观察者
AbstractHero* heroA = new HeroA;
AbstractHero* heroB = new HeroB;
AbstractHero* heroC = new HeroC;
//创建观察目标
AbstractBoss* bossA = new BossA;
bossA->addHero(heroA);
bossA->addHero(heroB);
bossA->addHero(heroC);
cout << "英雄C阵亡..." << endl;
bossA->deleteHero(heroC);
cout << "BOSS已被消灭 通知其他英雄停止攻击 进入待机状态" << endl;
bossA->notify();
}
int main() {
test01();
}
输出结果:
英雄A正在打BOSS
英雄B在打BOSS
英雄C在打BOSS
英雄C阵亡...
BOSS已被消灭 通知其他英雄停止攻击 进入待机状态
英雄A停止 待机状态
英雄B停止 待机状态
总结:这个模式其实最核心的地方就是观察者类中有不同的状态 而在观察目标类中传入一个观察者类 形成关联关系 当观察目标状态发生变化的时候,就可以调用观察者的内部函数改变观察者的状态