设计模式——策略模式(c++)

策略模式(Strategy Pattern)在 C++ 中的实现

1. 策略模式定义

策略模式定义了一系列算法(策略类),将每个算法封装起来,使它们可以相互替换,达到灵活使用不同策略的目的。在策略模式中,算法被封装成一系列具体策略类,作为抽象策略类的子类。根据实际需要选择合适的策略类来使用。

2. 策略模式角色

  • Context(环境类) :持有对抽象策略类的引用,这里指 Fighter 类。
  • Strategy(抽象策略类) :定义所支持的算法的公共接口,是所有具体策略类的父类,这里指 ItemStrategy 类。
  • ConcreteStrategy(具体策略类) :实现抽象策略类中声明的接口的子类,这里包括 ItemStrategy_BxdItemStrategy_DhdItemStrategy_Shd

3. 策略模式优缺点

优点

  • 以扩展的方式支持未来的变化,符合开闭原则。
  • 能有效替代大量不稳定的 ifswitch 条件分支。
  • 提高算法的复用性。
  • 改变环境对象的行为通过设置不同的策略类来实现。

缺点

  • 可能导致引入许多新策略类。
  • 使用策略时,调用者必须了解所有策略的功能,并选择合适的策略。

4. C++ 示例代码

以下是使用策略模式的 C++ 示例代码:

cpp 复制代码
#include <iostream>
#include <memory>
using namespace std;

// 前向声明
class Fighter;

// 策略基类
class ItemStrategy {
public:
    virtual void UseItem(Fighter* fighter) = 0; // 使用道具的纯虚函数
    virtual ~ItemStrategy() {} // 虚析构函数
};

// 战士类
class Fighter {
public:
    Fighter(int life, int magic, int attack)
        : life(life), magic(magic), attack(attack), itemStrategy(nullptr) {}

    void SetItemStrategy(ItemStrategy* strategy) {
        itemStrategy = strategy; // 设置当前的道具策略
    }

    void UseItem() {
        if (itemStrategy) {
            itemStrategy->UseItem(this); // 使用当前的道具策略
        }
    }

    int GetLife() const {
        return life; // 获取生命值
    }

    void SetLife(int life) {
        this->life = life; // 设置新的生命值
    }

    virtual ~Fighter() {} // 虚析构函数

protected:
    int life;   // 生命值
    int magic;  // 魔法值
    int attack; // 攻击力
    ItemStrategy* itemStrategy; // 当前使用的道具策略
};

// 补血丹策略类
class ItemStrategy_Bxd : public ItemStrategy {
public:
    virtual void UseItem(Fighter* fighter) override {
        fighter->SetLife(fighter->GetLife() + 200); // 补充生命值
    }
};

// 大还丹策略类
class ItemStrategy_Dhd : public ItemStrategy {
public:
    virtual void UseItem(Fighter* fighter) override {
        fighter->SetLife(fighter->GetLife() + 300); // 补充生命值
    }
};

// 守护丹策略类
class ItemStrategy_Shd : public ItemStrategy {
public:
    virtual void UseItem(Fighter* fighter) override {
        fighter->SetLife(fighter->GetLife() + 500); // 补充生命值
    }
};

// 战士类
class F_Warrior : public Fighter {
public:
    F_Warrior(int life, int magic, int attack) : Fighter(life, magic, attack) {}
};

// 法师类
class F_Mage : public Fighter {
public:
    F_Mage(int life, int magic, int attack) : Fighter(life, magic, attack) {}
};

int main() {
    // 创建一个战士角色
    Fighter* role_var = new F_Warrior(1000, 0, 200);
    cout << "初始生命值: " << role_var->GetLife() << endl;

    // 使用补血丹策略
    ItemStrategy* strategy = new ItemStrategy_Bxd();
    role_var->SetItemStrategy(strategy);
    role_var->UseItem();

    // 使用大还丹策略
    ItemStrategy* strategy2 = new ItemStrategy_Dhd();
    role_var->SetItemStrategy(strategy2);
    role_var->UseItem();

    // 输出最终生命值
    cout << "使用补血丹和大还丹后的生命值: " << role_var->GetLife() << endl;

    // 释放内存
    delete strategy;      // 释放补血丹策略对象
    delete strategy2;     // 释放大还丹策略对象
    delete role_var;      // 释放角色对象

    return 0;
}

5. 总结

策略模式是一种灵活的设计模式,可以帮助我们在不改变环境类的情况下,轻松地替换和添加新的策略。通过合理运用策略模式,可以有效地提升代码的可维护性和可扩展性。

相关推荐
诚丞成28 分钟前
计算世界之安生:C++继承的文水和智慧(上)
开发语言·c++
东风吹柳1 小时前
观察者模式(sigslot in C++)
c++·观察者模式·信号槽·sigslot
A懿轩A2 小时前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
思忖小下2 小时前
梳理你的思路(从OOP到架构设计)_简介设计模式
设计模式·架构·eit
大胆飞猪3 小时前
C++9--前置++和后置++重载,const,日期类的实现(对前几篇知识点的应用)
c++
1 9 J3 小时前
数据结构 C/C++(实验五:图)
c语言·数据结构·c++·学习·算法
夕泠爱吃糖3 小时前
C++中如何实现序列化和反序列化?
服务器·数据库·c++
长潇若雪3 小时前
《类和对象:基础原理全解析(上篇)》
开发语言·c++·经验分享·类和对象
liyinuo20174 小时前
嵌入式(单片机方向)面试题总结
嵌入式硬件·设计模式·面试·设计规范
染指11105 小时前
50.第二阶段x86游戏实战2-lua获取本地寻路,跨地图寻路和获取当前地图id
c++·windows·lua·游戏安全·反游戏外挂·游戏逆向·luastudio