C++策略模式实战:优雅切换算法

策略模式的定义与核心思想

策略模式(Strategy Pattern)是一种行为型设计模式,允许在运行时选择算法的行为。该模式将算法封装在独立的类中,使得它们可以相互替换而不影响客户端代码。核心思想是通过组合而非继承来实现算法的动态切换,提高代码的灵活性和可维护性。

在C++中,策略模式通常通过抽象基类或接口定义算法族,具体策略类实现这些接口,上下文类持有策略对象的引用并通过委托调用具体算法。

策略模式的结构与实现

策略模式包含三个主要角色:

  • Context(上下文):维护对策略对象的引用,通过接口调用具体策略。
  • Strategy(策略接口):定义所有支持的算法的公共接口。
  • ConcreteStrategy(具体策略):实现策略接口的具体算法。

以下是一个C++实现示例:

// 策略接口
class Strategy {
public:
    virtual void execute() const = 0;
    virtual ~Strategy() = default;
};

// 具体策略A
class ConcreteStrategyA : public Strategy {
public:
    void execute() const override {
        std::cout << "Executing Strategy A" << std::endl;
    }
};

// 具体策略B
class ConcreteStrategyB : public Strategy {
public:
    void execute() const override {
        std::cout << "Executing Strategy B" << std::endl;
    }
};

// 上下文类
class Context {
private:
    Strategy* strategy;
public:
    explicit Context(Strategy* s) : strategy(s) {}
    void setStrategy(Strategy* s) {
        strategy = s;
    }
    void executeStrategy() const {
        strategy->execute();
    }
};

// 使用示例
int main() {
    ConcreteStrategyA strategyA;
    ConcreteStrategyB strategyB;

    Context context(&strategyA);
    context.executeStrategy(); // 输出: Executing Strategy A

    context.setStrategy(&strategyB);
    context.executeStrategy(); // 输出: Executing Strategy B
}

策略模式的优势与应用场景

优势

  • 开闭原则:无需修改上下文即可扩展新策略。
  • 消除条件语句:避免复杂的条件分支逻辑。
  • 运行时灵活性:动态切换算法行为。

典型应用场景

  • 需要多种算法变体的场景(如排序、压缩、加密等)。
  • 算法需要独立于使用它的客户端。
  • 替换大量条件分支逻辑时。

策略模式与工厂模式的结合

策略模式常与工厂模式结合,通过工厂类创建具体策略对象,进一步解耦客户端代码。例如:

class StrategyFactory {
public:
    static Strategy* createStrategy(const std::string& type) {
        if (type == "A") return new ConcreteStrategyA();
        if (type == "B") return new ConcreteStrategyB();
        return nullptr;
    }
};

// 使用示例
Context context(StrategyFactory::createStrategy("A"));
context.executeStrategy();

实际案例:支付系统设计

假设需要实现一个支持多种支付方式的系统(信用卡、支付宝、微信支付),策略模式的实现如下:

// 支付策略接口
class PaymentStrategy {
public:
    virtual void pay(double amount) const = 0;
    virtual ~PaymentStrategy() = default;
};

// 具体支付策略
class CreditCardPayment : public PaymentStrategy {
public:
    void pay(double amount) const override {
        std::cout << "Paid " << amount << " via Credit Card" << std::endl;
    }
};

class AlipayPayment : public PaymentStrategy {
public:
    void pay(double amount) const override {
        std::cout << "Paid " << amount << " via Alipay" << std::endl;
    }
};

// 支付上下文
class PaymentContext {
private:
    PaymentStrategy* strategy;
public:
    explicit PaymentContext(PaymentStrategy* s) : strategy(s) {}
    void executePayment(double amount) const {
        strategy->pay(amount);
    }
};

// 使用示例
PaymentContext ctx(new AlipayPayment());
ctx.executePayment(100.0); // 输出: Paid 100 via Alipay

注意事项与常见问题

  1. 策略对象的生命周期管理:建议使用智能指针(如std::unique_ptr)避免内存泄漏。
  2. 性能开销:频繁创建和销毁策略对象可能影响性能,可考虑对象池优化。
  3. 过度设计:简单场景直接使用函数指针或Lambda可能更简洁。

通过合理应用策略模式,可以显著提升代码的可扩展性和可测试性,尤其在需要频繁变更或扩展算法的系统中效果显著。

BbS.okapop041.sbs/PoSt/1122_565136.HtM
BbS.okapop042.sbs/PoSt/1122_122594.HtM
BbS.okapop043.sbs/PoSt/1122_367067.HtM
BbS.okapop044.sbs/PoSt/1122_536233.HtM
BbS.okapop045.sbs/PoSt/1122_113144.HtM
BbS.okapop046.sbs/PoSt/1122_617900.HtM
BbS.okapop047.sbs/PoSt/1122_855520.HtM
BbS.okapop048.sbs/PoSt/1122_545669.HtM
BbS.okapop049.sbs/PoSt/1122_714342.HtM
BbS.okapop050.sbs/PoSt/1122_246293.HtM
BbS.okapop041.sbs/PoSt/1122_116226.HtM
BbS.okapop042.sbs/PoSt/1122_615445.HtM
BbS.okapop043.sbs/PoSt/1122_430344.HtM
BbS.okapop044.sbs/PoSt/1122_668615.HtM
BbS.okapop045.sbs/PoSt/1122_853582.HtM
BbS.okapop046.sbs/PoSt/1122_340687.HtM
BbS.okapop047.sbs/PoSt/1122_108422.HtM
BbS.okapop048.sbs/PoSt/1122_526345.HtM
BbS.okapop049.sbs/PoSt/1122_399763.HtM
BbS.okapop050.sbs/PoSt/1122_352600.HtM
BbS.okapop051.sbs/PoSt/1122_581217.HtM
BbS.okapop052.sbs/PoSt/1122_446362.HtM
BbS.okapop053.sbs/PoSt/1122_125881.HtM
BbS.okapop054.sbs/PoSt/1122_722794.HtM
BbS.okapop055.sbs/PoSt/1122_027779.HtM
BbS.okapop056.sbs/PoSt/1122_892051.HtM
BbS.okapop057.sbs/PoSt/1122_896979.HtM
BbS.okapop058.sbs/PoSt/1122_178345.HtM
BbS.okapop059.sbs/PoSt/1122_562877.HtM
BbS.okapop060.sbs/PoSt/1122_832930.HtM
BbS.okapop051.sbs/PoSt/1122_124251.HtM
BbS.okapop052.sbs/PoSt/1122_113675.HtM
BbS.okapop053.sbs/PoSt/1122_975428.HtM
BbS.okapop054.sbs/PoSt/1122_845717.HtM
BbS.okapop055.sbs/PoSt/1122_160807.HtM
BbS.okapop056.sbs/PoSt/1122_106608.HtM
BbS.okapop057.sbs/PoSt/1122_621837.HtM
BbS.okapop058.sbs/PoSt/1122_021812.HtM
BbS.okapop059.sbs/PoSt/1122_427589.HtM
BbS.okapop060.sbs/PoSt/1122_186600.HtM
BbS.okapop051.sbs/PoSt/1122_503976.HtM
BbS.okapop052.sbs/PoSt/1122_696855.HtM
BbS.okapop053.sbs/PoSt/1122_564891.HtM
BbS.okapop054.sbs/PoSt/1122_074749.HtM
BbS.okapop055.sbs/PoSt/1122_517646.HtM
BbS.okapop056.sbs/PoSt/1122_775797.HtM
BbS.okapop057.sbs/PoSt/1122_033012.HtM
BbS.okapop058.sbs/PoSt/1122_690598.HtM
BbS.okapop059.sbs/PoSt/1122_752122.HtM
BbS.okapop060.sbs/PoSt/1122_775917.HtM
BbS.okapop051.sbs/PoSt/1122_466569.HtM
BbS.okapop052.sbs/PoSt/1122_169097.HtM
BbS.okapop053.sbs/PoSt/1122_119054.HtM
BbS.okapop054.sbs/PoSt/1122_963885.HtM
BbS.okapop055.sbs/PoSt/1122_726708.HtM
BbS.okapop056.sbs/PoSt/1122_606790.HtM
BbS.okapop057.sbs/PoSt/1122_475635.HtM
BbS.okapop058.sbs/PoSt/1122_271017.HtM
BbS.okapop059.sbs/PoSt/1122_350674.HtM
BbS.okapop060.sbs/PoSt/1122_983267.HtM
BbS.okapop051.sbs/PoSt/1122_479777.HtM
BbS.okapop052.sbs/PoSt/1122_642617.HtM
BbS.okapop053.sbs/PoSt/1122_180076.HtM
BbS.okapop054.sbs/PoSt/1122_061502.HtM
BbS.okapop055.sbs/PoSt/1122_723205.HtM
BbS.okapop056.sbs/PoSt/1122_453596.HtM
BbS.okapop057.sbs/PoSt/1122_114597.HtM
BbS.okapop058.sbs/PoSt/1122_920982.HtM
BbS.okapop059.sbs/PoSt/1122_942305.HtM
BbS.okapop060.sbs/PoSt/1122_301278.HtM
BbS.okapop051.sbs/PoSt/1122_764359.HtM
BbS.okapop052.sbs/PoSt/1122_814007.HtM
BbS.okapop053.sbs/PoSt/1122_350753.HtM
BbS.okapop054.sbs/PoSt/1122_804828.HtM
BbS.okapop055.sbs/PoSt/1122_140333.HtM
BbS.okapop056.sbs/PoSt/1122_340434.HtM
BbS.okapop057.sbs/PoSt/1122_540235.HtM
BbS.okapop058.sbs/PoSt/1122_762536.HtM
BbS.okapop059.sbs/PoSt/1122_565469.HtM
BbS.okapop060.sbs/PoSt/1122_764466.HtM

#牛客AI配图神器#

全部评论

相关推荐

10-28 17:30
已编辑
华东交通大学 Java
iori2333:这太正常了 我字节面了四五轮 没有一次是在官网投递 都是hr主动捞
秋招笔试记录
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务