C++策略模式:灵活算法的优雅实现

策略模式的核心思想

策略模式属于行为型设计模式,通过定义一系列算法并将其封装成独立的类,使它们可以相互替换。该模式让算法的变化独立于使用它的客户端,提升系统的灵活性和可扩展性。

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

策略模式的实现结构

抽象策略类

定义所有支持的算法或行为的公共接口,通常为纯虚基类:

class Strategy {
public:
    virtual void execute() const = 0;
    virtual ~Strategy() = default;
};

具体策略类

实现抽象策略定义的接口,提供具体算法实现:

class ConcreteStrategyA : public Strategy {
public:
    void execute() const override {
        std::cout << "Executing Strategy A\n";
    }
};

class ConcreteStrategyB : public Strategy {
public:
    void execute() const override {
        std::cout << "Executing Strategy B\n";
    }
};

上下文类

维护策略对象的引用,通过策略接口与具体策略交互:

class Context {
private:
    std::unique_ptr<Strategy> strategy;
public:
    explicit Context(std::unique_ptr<Strategy>&& s) : strategy(std::move(s)) {}
    
    void setStrategy(std::unique_ptr<Strategy>&& s) {
        strategy = std::move(s);
    }
    
    void executeStrategy() const {
        strategy->execute();
    }
};

策略模式的应用示例

以下示例展示支付系统中不同支付策略的动态切换:

// 支付策略接口
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 << "Paying $" << amount << " via Credit Card\n";
    }
};

class PayPalPayment : public PaymentStrategy {
public:
    void pay(double amount) const override {
        std::cout << "Paying $" << amount << " via PayPal\n";
    }
};

// 支付上下文
class PaymentProcessor {
    std::unique_ptr<PaymentStrategy> strategy;
public:
    void setStrategy(std::unique_ptr<PaymentStrategy>&& s) {
        strategy = std::move(s);
    }
    
    void processPayment(double amount) const {
        strategy->pay(amount);
    }
};

// 客户端代码
int main() {
    PaymentProcessor processor;
    processor.setStrategy(std::make_unique<CreditCardPayment>());
    processor.processPayment(100.0);
    
    processor.setStrategy(std::make_unique<PayPalPayment>());
    processor.processPayment(200.0);
}

策略模式的优缺点分析

优点

  • 符合开闭原则:新增策略无需修改现有代码
  • 消除条件语句:避免使用大量if-else或switch-case判断不同策略
  • 提高复用性:相同策略可被不同上下文复用

缺点

  • 客户端必须了解所有策略:需要知道不同策略的区别以选择合适的策略
  • 增加对象数量:每个具体策略都会产生一个新类
  • 通信开销:策略与上下文可能需要通过接口传递额外数据

策略模式与状态模式的区别

虽然两者结构相似,但存在本质差异:

  • 策略模式:客户端主动选择策略,策略之间通常独立且无状态转换
  • 状态模式:状态转换由内部条件触发,状态之间可能存在关联关系

现代C++实现的改进

使用std::function和lambda表达式可以简化策略模式的实现:

class ModernContext {
private:
    std::function<void()> strategy;
public:
    void setStrategy(std::function<void()>&& s) {
        strategy = std::move(s);
    }
    
    void execute() const {
        strategy();
    }
};

// 客户端代码
ModernContext ctx;
ctx.setStrategy([](){ std::cout << "Lambda Strategy\n"; });
ctx.execute();

实际应用场景

  1. 排序算法选择:根据数据特征选择快速排序、归并排序等不同策略
  2. 压缩算法切换:支持ZIP、RAR等多种压缩格式
  3. 游戏AI行为:NPC根据环境选择攻击、逃跑或巡逻等不同行为策略
  4. 验证系统:支持密码验证、指纹验证、面部识别等多种验证方式

性能考量

在性能敏感场景中需注意:

  • 虚函数调用开销:策略模式涉及动态绑定,可能影响性能
  • 对象创建成本:频繁切换策略可能导致对象反复创建销毁
  • 内存占用:大量策略类会增加内存消耗

可通过对象池、策略缓存等技术进行优化。

BbS.okacop071.info/PoSt/1120_250675.HtM
BbS.okacop072.info/PoSt/1120_842276.HtM
BbS.okacop073.info/PoSt/1120_930727.HtM
BbS.okacop074.info/PoSt/1120_023962.HtM
BbS.okacop075.info/PoSt/1120_326080.HtM
BbS.okacop076.info/PoSt/1120_246601.HtM
BbS.okacop077.info/PoSt/1120_003959.HtM
BbS.okacop078.info/PoSt/1120_204792.HtM
BbS.okacop079.info/PoSt/1120_655035.HtM
BbS.okacop080.info/PoSt/1120_667548.HtM
BbS.okacop071.info/PoSt/1120_672229.HtM
BbS.okacop072.info/PoSt/1120_922789.HtM
BbS.okacop073.info/PoSt/1120_251581.HtM
BbS.okacop074.info/PoSt/1120_725288.HtM
BbS.okacop075.info/PoSt/1120_377538.HtM
BbS.okacop076.info/PoSt/1120_993887.HtM
BbS.okacop077.info/PoSt/1120_690307.HtM
BbS.okacop078.info/PoSt/1120_984111.HtM
BbS.okacop079.info/PoSt/1120_526499.HtM
BbS.okacop080.info/PoSt/1120_019894.HtM
BbS.okacop071.info/PoSt/1120_800303.HtM
BbS.okacop072.info/PoSt/1120_836642.HtM
BbS.okacop073.info/PoSt/1120_334887.HtM
BbS.okacop074.info/PoSt/1120_608689.HtM
BbS.okacop075.info/PoSt/1120_891100.HtM
BbS.okacop076.info/PoSt/1120_627740.HtM
BbS.okacop077.info/PoSt/1120_330379.HtM
BbS.okacop078.info/PoSt/1120_100449.HtM
BbS.okacop079.info/PoSt/1120_707866.HtM
BbS.okacop080.info/PoSt/1120_741987.HtM
BbS.okacop071.info/PoSt/1120_886880.HtM
BbS.okacop072.info/PoSt/1120_729695.HtM
BbS.okacop073.info/PoSt/1120_703122.HtM
BbS.okacop074.info/PoSt/1120_695357.HtM
BbS.okacop075.info/PoSt/1120_737369.HtM
BbS.okacop076.info/PoSt/1120_809924.HtM
BbS.okacop077.info/PoSt/1120_993587.HtM
BbS.okacop078.info/PoSt/1120_622614.HtM
BbS.okacop079.info/PoSt/1120_600490.HtM
BbS.okacop080.info/PoSt/1120_883319.HtM
BbS.okacop071.info/PoSt/1120_522462.HtM
BbS.okacop072.info/PoSt/1120_315132.HtM
BbS.okacop073.info/PoSt/1120_044032.HtM
BbS.okacop074.info/PoSt/1120_282253.HtM
BbS.okacop075.info/PoSt/1120_309453.HtM
BbS.okacop076.info/PoSt/1120_265849.HtM
BbS.okacop077.info/PoSt/1120_520381.HtM
BbS.okacop078.info/PoSt/1120_910574.HtM
BbS.okacop079.info/PoSt/1120_628042.HtM
BbS.okacop080.info/PoSt/1120_643523.HtM
BbS.okacop081.info/PoSt/1120_151041.HtM
BbS.okacop082.info/PoSt/1120_092874.HtM
BbS.okacop083.info/PoSt/1120_285129.HtM
BbS.okacop084.info/PoSt/1120_509683.HtM
BbS.okacop085.info/PoSt/1120_054942.HtM
BbS.okacop086.info/PoSt/1120_223820.HtM
BbS.okacop087.info/PoSt/1120_361421.HtM
BbS.okacop088.info/PoSt/1120_160770.HtM
BbS.okacop090.info/PoSt/1120_270817.HtM
BbS.okacop091.info/PoSt/1120_799610.HtM
BbS.okacop081.info/PoSt/1120_452792.HtM
BbS.okacop082.info/PoSt/1120_154661.HtM
BbS.okacop083.info/PoSt/1120_110387.HtM
BbS.okacop084.info/PoSt/1120_839748.HtM
BbS.okacop085.info/PoSt/1120_255740.HtM
BbS.okacop086.info/PoSt/1120_559728.HtM
BbS.okacop087.info/PoSt/1120_803812.HtM
BbS.okacop088.info/PoSt/1120_267797.HtM
BbS.okacop090.info/PoSt/1120_679291.HtM
BbS.okacop091.info/PoSt/1120_529186.HtM
BbS.okacop081.info/PoSt/1120_983659.HtM
BbS.okacop082.info/PoSt/1120_772378.HtM
BbS.okacop083.info/PoSt/1120_995656.HtM
BbS.okacop084.info/PoSt/1120_303962.HtM
BbS.okacop085.info/PoSt/1120_623460.HtM
BbS.okacop086.info/PoSt/1120_382483.HtM
BbS.okacop087.info/PoSt/1120_106014.HtM
BbS.okacop088.info/PoSt/1120_238787.HtM
BbS.okacop090.info/PoSt/1120_218416.HtM
BbS.okacop091.info/PoSt/1120_873086.HtM

#牛客AI配图神器#

全部评论

相关推荐

10-15 10:23
门头沟学院 Java
牛可乐的头像真牛:赶紧举报,这公司绝对是诈骗的,等你签约后工作一两个月后根据合同漏洞把你开除,并且要求你赔偿3w培训费,996是为了提前筛选心甘情愿签下合同容易受骗的群体,纯粹面向校招生精心设计的骗局
你见过哪些工贼行为
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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