以游戏情景举例:
情景:一个boss发动一个技能时会让自己的喽啰收到随机的增益效果。
提取一下主要需求:
1:随机增益效果
2:通知多个对象
其中1用策略模式+工厂模式来解决,2用观察者模式来解决
先解决1:
* 定义接口:
template<class Obj>class BuffBase {public:virtual void Computer(Obj*) = 0;//计算buff};
* 写几个子类:
template<class Obj>class HealthUpBuff :public BuffBase<Obj> {public:void Computer(Obj* Object) {Object->HealthValue*=2;std::cout << "HealthUp" << std::endl;}};template<class Obj>class MoveUpBuff :public BuffBase<Obj> {public:void Computer(Obj* Object) {Object->MoveSpeed *= 2;std::cout << "MoveUp" << std::endl;}};template<class Obj>class AttackUpBuff :public BuffBase<Obj> {public:void Computer(Obj* Object) {Object->AttackValue *= 2;std::cout << "AttackValueUp" << std::endl;}};
* 建立工厂:
enum BuffName{AttackUp, HealthUp, MoveSpeedUp,AttackSpeedUp};template<class Obj>class BuffFactor {std::unordered_map<BuffName, BuffBase<Obj>*> map;public:BuffFactor() {pushBuff(BuffName::AttackUp, new AttackUpBuff<Obj>());pushBuff(BuffName::HealthUp, new HealthUpBuff<Obj>());pushBuff(BuffName::MoveSpeedUp, new MoveUpBuff<Obj>());pushBuff(BuffName::AttackSpeedUp, new AttackSpeedUpBuff<Obj>());}void pushBuff(BuffName buffName, BuffBase<Obj>* buffBase) {if (buffBase == nullptr) {std::cout << "空指针" << std::endl;return;}if (map.count(buffName) != 0) {std::cout << "对象已存在" << std::endl;return;}map[buffName] = buffBase;}BuffBase<Obj>* GetBuff(BuffName buffName) {return map[buffName];}~BuffFactor()};
解决2:
写接口:
class Monster {public:float HealthValue = 10;float AttackValue = 10;float AttackSpeed = 10;float MoveSpeed = 10;virtual void GetBuff(BuffBase<Monster>* Buff) {Buff->Computer(this);}friend class BuffBase<Monster>;};
boss继承Monster,用list来存储观察者【小喽啰】
class Boss:Monster {std::list<Monster*> monsterVector;public:void pushMonster(Monster* NewMonster) {if (NewMonster == nullptr) return;monsterVector.push_back(NewMonster);}void Devolve() {for (auto t = monsterVector.begin(); t != monsterVector.end(); t++) {(*t)->GetBuff(Factor.GetBuff((BuffName)(rand() % 4)));}}};
完毕
总结一下:
用工厂模式+策略模式解决了随机的buff,即我们需要拓展buff效果时,只需要写继承BuffBase然即可,然后在工厂中增加新的buff即可,Monster和Boss我们是不需要动的,这里是高层和底层都依赖抽象,抽象不依赖底层细节,底层细节依赖抽象。
用观察模式解决了喽啰和boss之间的观察关系。