cpp: Strategy Pattern
Posted ®Geovin Du Dream Park™
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cpp: Strategy Pattern相关的知识,希望对你有一定的参考价值。
// Gold.h : 此文件包含 "Gold" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once //#ifndef GOLD_H //#define GOLD_H #ifndef _GOLD_ #define _GOLD_ #include <iostream> #include <sstream> #include <vector> #include "StrategyProfile.h" using namespace std; namespace DuJewelryStrategyPattern ////增加策略 //enum ItemAddlife // // LF_Corporation, // LF_Commerce, // LF_Shop, //; class StrategyProfile;//类前向声明 /// <summary> /// 黄金 父类 战斗者父类 /// </summary> class Gold public: Gold(int operation, int intellectual, int resource) :Poperation(operation), Pintellectual(intellectual), Presource(resource) virtual ~Gold() //public: // void UseItem(ItemAddlife djtype) //吃药补充生命值 // // if (djtype == LF_Corporation) //道具类型:补血丹 // // Poperation += 200; //补充200点生命值 // //if (主角中毒了) // // // // 停止中毒状态,也就是主角吃药后就不再中毒 // // // //if (主角处于狂暴状态) // // // // Poperation += 400; //额外再补充400点生命值 // // Pintellectual += 200; //魔法值也再补充200点 // // // // else if (djtype == LF_Commerce ) //大还丹 // // Poperation += 300; //补充300点生命值 // // else if (djtype == LF_Shop) //守护丹 // // Poperation += 500; //补充500点生命 // // //其他的一些判断逻辑,略...... // public: /// <summary> /// /// </summary> /// <param name="strategy"></param> void SetStrategyProfile(StrategyProfile* strategy); //设置道具使用的策略 /// <summary> /// / /// </summary> void UseItem(); //使用道具 /// <summary> /// 获取运营管理 /// </summary> /// <returns></returns> int GetOperation(); /// <summary> /// 设置运营管理 /// </summary> /// <param name="operation"></param> void SetOperation(int operation); // private: /// <summary> /// /// </summary> StrategyProfile* strategyProfile = nullptr; //C++11中支持这样初始化 protected: /// <summary> /// 运营管理 operation /// </summary> int Poperation; /// <summary> /// 智能技术 intellectual technology /// </summary> int Pintellectual; /// <summary> /// 资源配置 (整合)resource allocation /// </summary> int Presource; ; #endif // Gold.cpp 此文件包含 "Gold" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #include <iostream> #include "Gold.h" #include "StrategyProfile.h" using namespace std; namespace DuJewelryStrategyPattern /// <summary> /// 设置组合使用的策略 /// </summary> /// <param name="strategy"></param> void Gold::SetStrategyProfile(StrategyProfile* strategy) strategyProfile = strategy; /// <summary> /// 使用道具 /// </summary> void Gold::UseItem() strategyProfile->UseItem(); //this /// <summary> /// 获取运营管理 /// </summary> /// <returns></returns> int Gold::GetOperation() return Poperation; /// <summary> /// 设置运营管理 /// </summary> /// <param name="operation"></param> void Gold::SetOperation(int operation) Poperation = operation; // GoldCorporation.h : 此文件包含 "GoldCorporation" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef GOLDCORPORATION_H #define GOLDCORPORATION_H #include <iostream> #include <sstream> #include <vector> #include "Gold.h" #include "StrategyProfile.h" using namespace std; namespace DuJewelryStrategyPattern /// <summary> /// 子类 黄金公司 /// </summary> class GoldCorporation:public Gold public: /// <summary> /// /// </summary> /// <param name="operation"></param> /// <param name="intellectual"></param> /// <param name="resource"></param> GoldCorporation(int operation, int intellectual, int resource) :Gold(operation, intellectual, resource) ; #endif // StrategyProfile.h : 此文件包含 "StrategyProfile" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef GOLDCOMMERCE_H #define GOLDCOMMERCE_H #include <iostream> #include <sstream> #include <vector> #include "Gold.h" #include "StrategyProfile.h" using namespace std; namespace DuJewelryStrategyPattern /// <summary> /// 子类 商贸商会 /// </summary> class GoldCommerce:public Gold public: /// <summary> /// /// </summary> /// <param name="operation"></param> /// <param name="intellectual"></param> /// <param name="resource"></param> GoldCommerce(int operation, int intellectual, int resource) :Gold(operation, intellectual, resource) ; #endif // GoldShop.h : 此文件包含 "GoldShop" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef GOLDSHOP_H #define GOLDSHOP_H #include <iostream> #include <sstream> #include <vector> #include "Gold.h" #include "StrategyProfile.h" using namespace std; namespace DuJewelryStrategyPattern /// <summary> /// 子类 店舖 /// </summary> class GoldShop :public Gold public: /// <summary> /// /// </summary> /// <param name="operation"></param> /// <param name="intellectual"></param> /// <param name="resource"></param> GoldShop(int operation, int intellectual, int resource) :Gold(operation, intellectual, resource) ; #endif // StrategyProfile.h : 此文件包含 "StrategyProfile" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once //#ifndef STRATEGYPROFILE_H //#define STRATEGYPROFILE_H #ifndef _STRATEGYPROFILE_ #define _STRATEGYPROFILE_ #include <iostream> #include <sstream> #include <vector> #include "Gold.h" using namespace std; namespace DuJewelryStrategyPattern /// <summary> /// 策略组合 父类 策略类的父类 /// </summary> class StrategyProfile public: /// <summary> /// /// </summary> /// <param name="mainobj"></param> virtual void UseItem() = 0; //Gold* mainobj /// <summary> /// /// </summary> virtual ~StrategyProfile() ; #endif // StrategyOverallCost.h : 此文件包含 "StrategyOverallCost" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef STRATEGYOVERALLCOST_H #define STRATEGYOVERALLCOST_H #include <iostream> #include <sstream> #include <vector> #include "Gold.h" #include "StrategyProfile.h" using namespace std; namespace DuJewelryStrategyPattern /// <summary> /// 子类 成本领先战略(Overall cost leadership,也称低成本战略) 补血丹策略类 /// </summary> class StrategyOverallCost:public StrategyProfile public: /// <summary> /// /// </summary> /// <param name="mainobj"></param> virtual void UseItem(Gold* mainobj) mainobj->SetOperation(mainobj->GetOperation() + 200); //补充200点生命值 ; #endif // StrategyMarketFocus.h : 此文件包含 "StrategyMarketFocus" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef STRATEGYMARKETFOCUS_H #define STRATEGYMARKETFOCUS_H #include <iostream> #include <sstream> #include <vector> #include "Gold.h" #include "StrategyProfile.h" using namespace std; namespace DuJewelryStrategyPattern /// <summary> ///子类 专一化战略(Market focus/focus strategy),也称集中化战略(集中策略)、目标集中战略、目标聚集战略、目标聚集性战略 大还丹策略类 /// </summary> class StrategyMarketFocus :public StrategyProfile public: /// <summary> /// /// </summary> /// <param name="mainobj"></param> virtual void UseItem(Gold* mainobj) mainobj->SetOperation(mainobj->GetOperation() + 500); //补充500点生命值 ; #endif // StrategyDifferentiation.h : 此文件包含 "StrategyDifferentiation" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef STRATEGYDIFFERENTIATION_H #define STRATEGYDIFFERENTIATION_H #include <iostream> #include <sstream> #include <vector> #include "Gold.h" #include "StrategyProfile.h" using namespace std; namespace DuJewelryStrategyPattern /// <summary> ///子类 差异化战略(differentiation/differentiation strategy) 守护丹策略类 /// </summary> class StrategyDifferentiation :public StrategyProfile public: /// <summary> /// /// </summary> /// <param name="mainobj"></param> virtual void UseItem(Gold* mainobj) mainobj->SetOperation(mainobj->GetOperation() + 300); //补充300点生命值 ; #endif
// SupplierGold.h : 此文件包含 "SupplierGold" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef SUPPLIERGOLD_H #define SUPPLIERGOLD_H #include <iostream> #include <sstream> #include <vector> using namespace std; namespace DuJewelryStrategyPatternUnabstract /// <summary> /// 黄金供应商 /// </summary> class SupplierGold public: /// <summary> /// /// </summary> void getInfo() cout << "这是一黄金供应商" << endl; //其他代码略...... ; #endif // SupplierPearl.h : 此文件包含 "SupplierPearl" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef SUPPLIERPEARL_H #define SUPPLIERPEARL_H #include <iostream> #include <sstream> #include <vector> using namespace std; namespace DuJewelryStrategyPatternUnabstract /// <summary> /// 珍珠供应商 /// </summary> class SupplierPearl public: /// <summary> /// /// </summary> void getInfo() cout << "这是一珍珠供应商" << endl; //其他代码略...... ; #endif // SupplierJade.h : 此文件包含 "SupplierJade" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef SUPPLIERJADE_H #define SUPPLIERJADE_H #include <iostream> #include <sstream> #include <vector> using namespace std; namespace DuJewelryStrategyPatternUnabstract /// <summary> /// 玉供应商 /// </summary> class SupplierJade public: /// <summary> /// /// </summary> void getInfo() cout << "这是一玉供应商" << endl; //其他代码略...... ; #endif // SupplierDiamond.h : 此文件包含 "SupplierDiamond" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef SUPPLIERDIAMOND_H #define SUPPLIERDIAMOND_H #include <iostream> #include <sstream> #include <vector> using namespace std; namespace DuJewelryStrategyPatternUnabstract /// <summary> /// 钻石供应商 /// </summary> class SupplierDiamond public: /// <summary> /// /// </summary> void getInfo() cout << "这是一钻石供应商" << endl; //其他代码略...... ; #endif // SupplierIncrement.h : 此文件包含 "SupplierIncrement" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef SUPPLIERINCREMENT_H #define SUPPLIERINCREMENT_H #include <iostream> #include <sstream> #include <vector> #include "SupplierDiamond.h" #include "SupplierGold.h" #include "SupplierJade.h" #include "SupplierPearl.h" using namespace std; namespace DuJewelryStrategyPatternUnabstract /// <summary> /// /// </summary> class SupplierIncrement public: /// <summary> /// 创建 黄金供应商 /// </summary> /// <param name="pobj"></param> void createSupplierGold(SupplierGold* pobj) //进行创建处理...... pobj->getInfo(); //可以调用成员函数 //其他代码略...... public: /// <summary> /// 创建 钻石供应商 /// </summary> /// <param name="pobj"></param> void createSupplierDiamond(SupplierDiamond* pobj) //进行创建处理...... pobj->getInfo(); //可以调用成员函数 public: /// <summary> /// 创建 珍珠供应商 /// </summary> /// <param name="pobj"></param> void createSupplierPearl(SupplierPearl* pobj) //进行创建处理...... pobj->getInfo(); //可以调用成员函数 public: /// <summary> /// 创建 玉供应商 /// </summary> /// <param name="pobj"></param> void createSupplierJade(SupplierJade* pobj) //进行创建处理...... pobj->getInfo(); //可以调用成员函数 ; #endif
// GeovinDu.h : 此文件包含 "GeovinDu" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef GEOVINDU_H #define GEOVINDU_H #include <iostream> #include <sstream> #include <vector> #include "Gold.h" #include "StrategyProfile.h" using namespace std; namespace DuJewelryStrategyPattern /// <summary> /// 业务处理 /// </summary> class GeovinDu private: public: void displayUnabstract(); ; #endif // GeovinDu.cpp : 此文件包含 "GeovinDu" 类。策略模式 Strategy Pattern C++ 14 // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. #include "GeovinDu.h" #include <iostream> #include <sstream> #include <vector> #include "Gold.h" #include "GoldShop.h" #include "GoldCommerce.h" #include "GoldCorporation.h" #include "SupplierDiamond.h" #include "SupplierGold.h" #include "SupplierJade.h" #include "SupplierPearl.h" #include "SupplierIncrement.h" #include "StrategyProfile.h" #include "StrategyDifferentiation.h" #include "StrategyMarketFocus.h" #include "StrategyOverallCost.h" using namespace std; using namespace DuJewelryStrategyPatternUnabstract; namespace DuJewelryStrategyPattern /// <summary> /// /// </summary> void GeovinDu::displayUnabstract() //Gold* prole_war = new SupplierIncrement(1000, 0, 200);//这没有采用工厂模式,如果主角很多,可以考虑采用工厂模式创建对象 //prole_war->UseItem(LF_GOEIVNDU); //delete prole_war; //创建主角 Gold* prole_shop = new GoldShop(1000, 0, 200); //成本策略 //StrategyProfile* strateby; //StrategyOverallCost d; //strateby = &d; /* StrategyProfile* strateby = new StrategyOverallCost(); //创建成本策略 prole_shop->SetStrategyProfile(strateby); //主角设置大还丹策略,准备吃大还丹 prole_shop->UseItem(); //主角吃大还丹 //差异化战略 StrategyProfile* strateby2 = new StrategyDifferentiation(); //创建差异化战略 prole_shop->SetStrategyProfile(strateby2); //主角设置策略 prole_shop->UseItem(); //主角用策略 //释放资源 delete strateby; delete strateby2; delete prole_shop; */ //------------------------------ DuJewelryStrategyPatternUnabstract::SupplierGold* pobjud = new DuJewelryStrategyPatternUnabstract::SupplierGold(); DuJewelryStrategyPatternUnabstract::SupplierIncrement* pobjwar = new DuJewelryStrategyPatternUnabstract::SupplierIncrement(); pobjwar->createSupplierGold(pobjud); //创建一个黄金供应商 DuJewelryStrategyPatternUnabstract::SupplierDiamond* pobjelm = new DuJewelryStrategyPatternUnabstract::SupplierDiamond(); pobjwar->createSupplierDiamond(pobjelm);//创建一个钻石供应商 //资源释放 delete pobjwar; delete pobjud; delete pobjelm;
调用:
// ConsoleDuStrategyPattern.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // Jewelry Builder Pattern 生成器模式 建造者模式、Builder // // 2023年5月1日 涂聚文 Geovin Du Visual Studio 2022 edit. // #define _UNICODE #include <iostream> #include "GeovinDu.h" #include "SupplierIncrement.h" #ifdef _DEBUG //只在Debug(调试)模式下 #ifndef DEBUG_NEW #define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) //重新定义new运算符 #define new DEBUG_NEW #endif #endif //#include <boost/type_index.hpp> using namespace std; //#pragma warning(disable : 4996) using namespace DuJewelryStrategyPattern; using namespace DuJewelryStrategyPatternUnabstract; int main() std::cout << "Hello World!!Programa Olá Mundo!涂聚文 Geovin Du\\n"; GeovinDu geovin; geovin.displayUnabstract(); system("pause"); return 0; // 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 // 调试程序: F5 或调试 >“开始调试”菜单 // 入门使用技巧: // 1. 使用解决方案资源管理器窗口添加/管理文件 // 2. 使用团队资源管理器窗口连接到源代码管理 // 3. 使用输出窗口查看生成输出和其他消息 // 4. 使用错误列表窗口查看错误 // 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目 // 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件 #define UNICODE
输出:
Hello World!!Programa Olá Mundo!涂聚文 Geovin Du 这是一黄金供应商 这是一钻石供应商 请按任意键继续. . .
Strategy Pattern
class Character; class King; class Queen; class Knight; class Girl; class Character { public: Character() {} ~Character() {} public: virtual void fight(); public: void setName(std::string s); std::string& getName(); private: std::string name_; }; void Character::setName(std::string s) { name_ = s; } std::string& Character::getName() { return name_; } void Character::fight() { printf("Fight with sword. "); } class King : public Character { }; class Queen : public Character { public: void fight() { printf("A queen never fight. "); } }; class Women : public Character { public: void fight() { printf("A woman never fight. "); } }; class Children : public Character { public: void fight() { printf("A child never fight. "); } }; class Knight : public Character { };
Traditionally, a King and a Knight will fight in a war defending the land. A Queen and a girl will not participate in the war, thus the Queen and Girl character
inheritated from Chacracter will rewrite virtual funtion fight();
Somewhat one day, the kingdom is threatened by a savage troup, which have more enormous soldiers than this kingdom. Thus the king has decided to make the girl & queen & child
join the army to defend the land.
In inheritance & implementation-orientated programming as above, the Queen & Women & Children class must change their fight() funtion. This will be trivial.
To simplify this process, we use strategy pattern.
class Character; class King; class Queen; class Knight; class Women; class Children; class Weapon; class Sword; class Axe; class Nothing; class Weapon { public: Weapon() {} ~Weapon() {} public: virtual void useWeapon(); }; class Sword : public Weapon { public: void useWeapon() { printf("Fight using sword. "); } }; class Axe : public Weapon { public: void useWeapon() { printf("Fight using axe. "); } }; class Nothing : public Weapon { public: void useWeapon() { printf("No need to fight. "); } }; class Character { public: Character() {} ~Character() { delete weapon_; } public: void fight() { weapon_->useWeapon(); } void setWeapon(Weapon* w) { weapon_ = w; } private: Weapon* weapon_; std::string name_; }; class Queen : public Character { public: Queen() { setWeapon(new Nothing); } }; class Women : public Character { public: Women() { setWeapon(new Nothing); } }; class Children : public Character { public: Children() { setWeapon(new Nothing); } }; class King : public Character { public: King() { setWeapon(new Sword); } }; class Knight : public Character { public: Knight() { setWeapon(new Axe); } };
And now the same thing happened when the savage troop came. The king decided to arm all the women & children & queen. What can the king do?
The king only has to modify the Nothing class to fight with sticks, you know, there are not enough swords for the children and women (全民皆兵)
1.
class Nothing : public Weapon { public: void useWeapon() { printf("Fight with sticks. "); } }; 2. for all women, children w.setWeapon(new Sword); c.setWeapon(new Sword);
策略模式
Pros:
1. 可以批量地修改算法,而不用一个个地去修改角色的动作;
2. 对于新添加的角色,只需要让角色拥有对应的武器超类即可,所有角色战斗所调用的函数都是fight();
3. 可以在运行时改变角色的行为;
Cons:
1. 如果角色的行为不会出现变化,那么就没有必要多此一举,增加代码的复杂度;
2. 用户需要了解各种不同的strategy的不同用处和用法;
总结:
策略模式把行为/算法封装成类,这些类与拥有对应行为/算法的类相互独立。客户类通过使用组合(composition)来拥有对应的行为/算法;
从代码维护角度,只需要修改特定行为类的实现,即可批量修改使用此行为类的行为;
从客户使用角度,可以在运行时改变类的行为;
reference:
1. https://refactoring.guru/design-patterns/strategy
2. Head First Design Patterns
以上是关于cpp: Strategy Pattern的主要内容,如果未能解决你的问题,请参考以下文章