(5)策略模式

策略模式的核心思想,定义一系列算法或行为,把它们封装起来,并且使它们可以互相替换。
 - 客户端可以在运行时动态切换策略
 - 避免 if-else 或 switch 判断不同算法
 - 提高扩展性和可维护性
设计思想
 - 定义一个策略接口
 - 每种算法实现一个具体策略类
 - 上下文类持有策略,通过多态调用
// ============ 策略类:策略接口 ============
class PaymentStrategy {
public:
    virtual ~PaymentStrategy() = default;
    virtual void pay(int amount) = 0;
};

// ============ 具体策略 ============

class Alipay : public PaymentStrategy {
public:
    void pay(int amount) override {
        std::cout << "使用支付宝支付: " << amount << " 元\n";
    }
};

class WeChatPay : public PaymentStrategy {
public:
    void pay(int amount) override {
        std::cout << "使用微信支付: " << amount << " 元\n";
    }
};

class BankCard : public PaymentStrategy {
public:
    void pay(int amount) override {
        std::cout << "使用银行卡支付: " << amount << " 元\n";
    }
};
// ============ 持有策略:上下文(使用策略的类) ============
class PaymentContext {
private:
    std::unique_ptr<PaymentStrategy> strategy_;// 基类指针

public:
    // 注入策略
    explicit PaymentContext(std::unique_ptr<PaymentStrategy> strategy)
        : strategy_(std::move(strategy)) {}

    // 切换策略
    void setStrategy(std::unique_ptr<PaymentStrategy> strategy) {
        strategy_ = std::move(strategy);
    }

    // 执行支付
    void executePayment(int amount) {
        if (strategy_) {
            strategy_->pay(amount);
        } else {
            std::cout << "未设置支付策略!\n";
        }
    }
};
int main() {
    PaymentContext context{std::make_unique<Alipay>()};
    
    // 使用支付宝支付
    context.executePayment(100);  // 输出: 使用支付宝支付: 100 元

    // 切换为微信支付
    context.setStrategy(std::make_unique<WeChatPay>());
    context.executePayment(200);  // 输出: 使用微信支付: 200 元

    // 切换为银行卡
    context.setStrategy(std::make_unique<BankCard>());
    context.executePayment(300);  // 输出: 使用银行卡支付: 300 元

    return 0;
}
进阶
 - 保留策略模式的核心思想:算法可替换
 - 使用模板实现零成本抽象
 - 无需继承、无需虚函数表
 - 支持运行时或编译时选择策略
// ============ 具体策略(普通类,无需继承) ============
struct Alipay {
    void pay(int amount) {
        std::cout << "使用支付宝支付: " << amount << " 元\n";
    }
};

struct WeChatPay {
    void pay(int amount) {
        std::cout << "使用微信支付: " << amount << " 元\n";
    }
};

struct BankCard {
    void pay(int amount) {
        std::cout << "使用银行卡支付: " << amount << " 元\n";
    }
};
// ============ 模板化上下文(使用策略) ============
template <typename Strategy>
class PaymentContext {
private:
    Strategy strategy_;

public:
    // 构造时传入策略(或直接使用默认构造)
    explicit PaymentContext(Strategy s = Strategy{}) : strategy_(std::move(s)) {}

    // 执行支付(编译时决定调用哪个 pay)
    void pay(int amount) {
        strategy_.pay(amount);
    }

    // 允许更换策略(如果需要运行时更换,可配合其他机制)
    void setStrategy(Strategy s) {
        strategy_ = std::move(s);
    }
};
int main() {
    // === 编译时选择策略 ===
    // 使用支付宝
    PaymentContext<Alipay> alipayContext;
    alipayContext.pay(100);

    // 使用微信
    PaymentContext<WeChatPay> wechatContext;
    wechatContext.pay(200);

    // 使用银行卡
    PaymentContext<BankCard> bankContext;
    bankContext.pay(300);

    return 0;
}
posted @ 2018-12-11 23:59  osbreak  阅读(178)  评论(0)    收藏  举报