C++基本设计模式03
此章的模式比较常用,重要!
9 策略模式: 多种东西被某个人或物考虑选择。
例一个人可以使用中武器,商场可以使用多种促销策略。实际上就是合成复用法则的设计思想,和开车的例子一模一样。
*/
例子1:一个人使用多种武器。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
/*
策略模式: 在继承中 一个人可以使用中武器
实际上就是合成复用法则的设计思想 和开车的例子一模一样
*/
class WeaponStrategy{
public:
virtual void UseWeapon()=0;
};
class Knief:public WeaponStrategy{
public:
virtual void UseWeapon(){
cout<<"使用小刀"<<endl;
}
};
class AK47:public WeaponStrategy{
public:
virtual void UseWeapon(){
cout<<"使用AK47"<<endl;
}
};
//人可以使用多种武器
class Character{
public:
//1 提供设置哪种武器的方法 相当于构造函数
void setWeapon(WeaponStrategy* weapon){
m_weapon=weapon; //容易发生浅拷贝 建议重写深拷贝 为了易懂我没写
}
//2 执行使用武器
void ThrowWeapon(){
m_weapon->UseWeapon();
}
public:
WeaponStrategy* m_weapon;
};
void test01(){
Character* cha=new Character;
//通过人去设置构造小刀武器
WeaponStrategy* knief=new Knief;
cha->setWeapon(knief);
//执行武器
cha->ThrowWeapon();
//同样构造并使用武器AK47
WeaponStrategy* ak47=new AK47;
cha->setWeapon(ak47);
cha->ThrowWeapon();
delete cha;
delete knief;
delete ak47;
}
int main(){
test01();
return 0;
}
例子2:商场多个促销策略。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//抽象策略类
class AbstractStrategy{
public:
virtual int CaculateMoney(int) = 0;
};
//8折策略
class StrategySaleByEight : public AbstractStrategy{
public:
virtual int CaculateMoney(int money){
return money * 0.8;
}
};
//满200 返现100策略
class StrategySale200Return100 : public AbstractStrategy{
public:
virtual int CaculateMoney(int money){
//他这样写属实亏啊 减去多次100 还不如用我的
//return money - (money / 200) * 100;
return money-100;
}
};
//超市购物类
class Shopping{
public:
Shopping(){
pStrategy = NULL;
}
//设置调度策略
void setStrategy(AbstractStrategy* strategy){
pStrategy = strategy;
}
//使用该调度方法的方法
void PayMoney(int money){
int realMoney = 0;
if (NULL == pStrategy){
realMoney = money;
}
else{
//根据人看到的钱判断调用哪个策略 不需要写代码判断 所以可以直接调
realMoney = pStrategy->CaculateMoney(money);
}
cout << "折前价格:" << money << ",折后价格:" << realMoney << "元!" << endl;
}
private:
AbstractStrategy* pStrategy;
};
void test01(){
Shopping* shopping = new Shopping;
AbstractStrategy* strategy = NULL;
cout << "逢活动 八折优惠" << endl;
strategy = new StrategySaleByEight;
shopping->setStrategy(strategy); //设置商场活动为8折优惠
shopping->PayMoney(600);
delete strategy;
cout << "再次逢活动 满200 返现100" << endl;
strategy = new StrategySale200Return100;
shopping->setStrategy(strategy);
shopping->PayMoney(900);
delete strategy;
delete shopping;
}
总结策略模式:多种东西被某个人或物考虑选择。例子,一个人可以使用多种武器;商场可以使用多种促销策略;实际上就是合成复用法则的设计思想,和开车的例子一模一样。难点在于人类即商店类或者说所有策略模式的使用类,都必须需要有 :
1)设置的方法即调度策略 。
2)并且要有使用该策略方法的方法。
10 命令模式: 本质是对请求进行封装,一个请求对应于一个命令,将发出命令的责任和执行命令的责任分割开。
步骤:
1) 将所有请求封装在一个类中。
2) 定义一个抽象类并提供具体命令的共同接口。—共同接口有点难找 需要花点时间。
3) 继承命令抽象类 ,遵循一个请求对应一个命令。
4) 服务端将客户端发送的请求,用方法记录在数据成员容器中,然后在依次调用方法开始处理请求。
例子1:协议封装请求。服务器先记录请求,并依次处理发送的的请求。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<queue>
using namespace std;
//封装多个请求
class HandleProtocol{
public:
void AddMoney(){
cout<<"增加金币请求"<<endl;
}
void AddDiamond(){
cout<<"增加钻石请求"<<endl;
}
void AddEquipment(){
cout<<"增加装备请求"<<endl;
}
void AddLevel(){
cout<<"增加等级请求"<<endl;
}
};
//抽象类命令
class AbstractHandleCommand{
public:
//共同处理请求接口
virtual void handle()=0;
};
//具体类命令 一个请求对应一个具体命令
class AddMoneyCommand:public AbstractHandleCommand{
public:
void setAddMoneyProtocol(HandleProtocol* protocol){
m_protocol=protocol;
}
//重写处理请求接口
virtual void handle(){
m_protocol->AddMoney();
}
public:
HandleProtocol* m_protocol;
};
//增加钻石请求处理
class AddDiamondCommand:public AbstractHandleCommand{
public:
void setAddDiamondProtocol(HandleProtocol* protocol){
m_protocol=protocol;
}
//重写处理请求接口
virtual void handle(){
m_protocol->AddDiamond();
}
public:
HandleProtocol* m_protocol;
};
//增加装备请求处理
class AddEquipmentCommand:public AbstractHandleCommand{
public:
void setAddEquipmentProtocol(HandleProtocol* protocol){
m_protocol=protocol;
}
//重写处理请求接口
virtual void handle(){
m_protocol->AddEquipment();
}
public:
HandleProtocol* m_protocol;
};
//增加等级请求处理
class AddLevelCommand:public AbstractHandleCommand{
public:
void setAddLevelProtocol(HandleProtocol* protocol){
m_protocol=protocol;
}
//重写处理请求接口
virtual void handle(){
m_protocol->AddLevel();
}
public:
HandleProtocol* m_protoc