古月不傲 发表于 2020-11-15 11:10

策略模式

本帖最后由 古月不傲 于 2020-11-15 11:36 编辑

#include <iostream>

#include <list>

using namespace std;

// 策略模式
namespace strategy_pattern {
enum targets
{
    MONSTER_DOG,
    MONSTER_CAT,
    MONSTER_MOUSE
};
// 抽象英雄类
class abstract_hero
{
public:
    virtual void attack(targets type) = 0;
    virtual void walk(double x, double y, double z) = 0;
    virtual void cast_skills() = 0;
    virtual void print() = 0;
    virtual ~abstract_hero() {}
};

// adc
class adc : public abstract_hero
{
public:
    adc(const string &name, double blood, double mana, double max_blood, double max_mana, list<string> &skills): m_name(name)
    , m_blood(blood)
    , m_mana(mana)
    , m_max_blood(max_blood)
    , m_max_mana(max_mana)
    , m_skills{}
    {
      for (auto &it : skills) {
            this->m_skills.push_back(it);
      }
    }
    virtual void attack(targets type) {
      printf("攻击%d号目标\n", type);
    }
    virtual void walk(double x, double y, double z) {
      printf("移动到:%lf,%lf,%lf\n", x, y, z);
    }
    virtual void cast_skills() {
      for (auto &it: this->m_skills) {
            printf("释放:%s\n", it.c_str());
      }
    }
   virtual void print() {
      printf("角色:%s\n", this->m_name.c_str());
      printf("当前血量:%.0lf\n", this->m_blood);
      printf("当前蓝量:%.0lf\n", this->m_mana);
      printf("最大血量:%.0lf\n", this->m_max_blood);
      printf("最大蓝量:%.0lf\n", this->m_max_mana);
      printf("技能:\n");
      for (auto &it: this->m_skills) {
            printf("\t%s\n", it.c_str());
      }
    }
private:
    string m_name;          // 人物名
    double m_blood;         // 人物当前血量
    double m_mana;          // 人物当前蓝量
    double m_max_blood;   // 人物最大血量
    double m_max_mana;      // 人物最大蓝量
    list<string> m_skills;// 人物技能名称
};

// apc
class apc : public abstract_hero
{
public:
    apc(const string &name, double blood, double mana, double max_blood, double max_mana, list<string> &skills): m_name(name)
    , m_blood(blood)
    , m_mana(mana)
    , m_max_blood(max_blood)
    , m_max_mana(max_mana)
    , m_skills{}
    {
      for (auto &it : skills) {
            this->m_skills.push_back(it);
      }
    }
    virtual void attack(targets type) {
      printf("攻击%d号目标\n", type);
    }
    virtual void walk(double x, double y, double z) {
      printf("移动到:%lf,%lf,%lf\n", x, y, z);
    }
    virtual void cast_skills() {
      for (auto &it: this->m_skills) {
            printf("释放:%s\n", it.c_str());
      }
    }
    virtual void print() {
      printf("角色:%s\n", this->m_name.c_str());
      printf("当前血量:%.0lf\n", this->m_blood);
      printf("当前蓝量:%.0lf\n", this->m_mana);
      printf("最大血量:%.0lf\n", this->m_max_blood);
      printf("最大蓝量:%.0lf\n", this->m_max_mana);
      printf("技能:\n");
      for (auto &it: this->m_skills) {
            printf("\t%s\n", it.c_str());
      }
    }
private:
    string m_name;          // 人物名
    double m_blood;         // 人物当前血量
    double m_mana;          // 人物当前蓝量
    double m_max_blood;   // 人物最大血量
    double m_max_mana;      // 人物最大蓝量
    list<string> m_skills;// 人物技能名称
};

// 通过一个中间类 使用指定对象
class strategy
{
public:
    strategy(abstract_hero *hero) : m_hero(hero) {}
    void attack(targets type) {
      this->m_hero->attack(type);
    }
    void walk(double x, double y, double z) {
      this->m_hero->walk(x, y, z);
    }
    void cast_skills() {
      this->m_hero->cast_skills();
    }
    void print() {
      this->m_hero->print();
    }
private:
    abstract_hero *m_hero;
};
}

// 可以看出对比工厂模式 工厂模式属于单纯的创建对象型 策略模式属于先创建对象再使用对象的方法 属于行为型
int main(void)
{
    using namespace strategy_pattern;

    list<string> ashe_skills;
    ashe_skills.push_back("射手的专注");
    ashe_skills.push_back("万箭齐发");
    ashe_skills.push_back("鹰击长空");
    ashe_skills.push_back("魔法水晶箭");
    adc ashe("寒冰射手", 300, 200, 300, 200, ashe_skills);

    list<string> ryze_skills;
    ryze_skills.push_back("超负荷");
    ryze_skills.push_back("符文禁锢");
    ryze_skills.push_back("法术涌动");
    ryze_skills.push_back("曲境折跃");
    apc ryze("瑞兹", 400, 250, 400, 250, ryze_skills);
   
    strategy *stgy_ashe = new strategy(&ashe);
    stgy_ashe->attack(MONSTER_DOG);
    stgy_ashe->cast_skills();
    stgy_ashe->walk(50, 60, 3);
    stgy_ashe->print();

    strategy *stgy_ryze = new strategy(&ryze);
    stgy_ryze->attack(MONSTER_MOUSE);
    stgy_ryze->cast_skills();
    stgy_ryze->walk(100, 120, 5);
    stgy_ryze->print();

    delete stgy_ryze;
    delete stgy_ashe;
   
    return 0;
}

// 总结
// 优点:不用改变中间类的代码 如果需要新的行为 只需要再构建一个行为类
// 缺点:如果要多种不用的行为 需要创建很多不用行为的类

备注:这个例子不适合 写完才发现很糟糕,你可以从加密的角度去思考,加密有很多种,很适合这种模式。

大公无私 发表于 2020-11-15 11:53

插个眼   留着备用

zhu0797zhu 发表于 2020-11-15 12:37

游戏人士正需要。
页: [1]
查看完整版本: 策略模式