标签:hat position fir har 添加 dom The art virt
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.\n"); } class King : public Character { }; class Queen : public Character { public: void fight() { printf("A queen never fight.\n"); } }; class Women : public Character { public: void fight() { printf("A woman never fight.\n"); } }; class Children : public Character { public: void fight() { printf("A child never fight.\n"); } }; 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.\n"); } }; class Axe : public Weapon { public: void useWeapon() { printf("Fight using axe.\n"); } }; class Nothing : public Weapon { public: void useWeapon() { printf("No need to fight.\n"); } }; 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.\n"); } }; 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
标签:hat position fir har 添加 dom The art virt
原文地址:https://www.cnblogs.com/satchel/p/10097015.html