设计模式-策略模式

策略模式(Strategy Pattern)

一、什么是策略模式

策略模式是一种行为型设计模式,它定义了一系列算法(策略),并将每个算法封装起来,使它们可以互相替换。
策略模式让算法的变化独立于使用算法的客户端。

二、解决了什么问题

  • 当系统中有多种算法(或行为)可以替换时,如果写在 if-elseswitch 语句中,会导致代码臃肿、难以维护。 (不是所有的 if 都应该被替换为策略模式。对于逻辑简单、变化不大的分支,使用 if-else 反而更直观;只有在分支逻辑复杂、需要灵活扩展或动态切换行为时,策略模式才能体现出优势。)
  • 策略模式通过面向接口编程,将不同的算法封装为独立类,使得它们能灵活切换。

三、模式的核心思想

  • 定义一个抽象策略接口,声明算法的共同方法。
  • 每个具体策略类实现该接口,封装具体算法。
  • 上下文类(Context)持有一个策略对象,并在需要时调用该策略的方法。

四、结构图

抽象策略 Strategy
    └── 算法方法 algorithm()

具体策略 ConcreteStrategyA
    └── 实现 algorithm()

具体策略 ConcreteStrategyB
    └── 实现 algorithm()

上下文 Context
    └── 持有 Strategy 引用,调用其方法

五、代码样例

  • 场景:我们日常购物时,支付方式可能是 支付宝 / 微信 / 银行卡。

不使用策略模式(写死if-else)

#include <iostream>
#include <string>
using namespace std;

class Payment {
public:
    void pay(string type) {
        if (type == "Alipay") {
            cout << "使用支付宝支付\n";
        } else if (type == "WeChat") {
            cout << "使用微信支付\n";
        } else if (type == "Bank") {
            cout << "使用银行卡支付\n";
        } else {
            cout << "未知支付方式\n";
        }
    }
};

int main() {
    Payment p;
    p.pay("Alipay");
    p.pay("WeChat");
    return 0;
}

使用策略模式

抽象策略接口

class PayStrategy {
public:
    virtual ~PayStrategy() {}
    virtual void pay() = 0;
};

以下为具体策略

class Alipay : public PayStrategy {
public:
    void pay() override {
        cout << "使用支付宝支付\n";
    }
};

class WeChatPay : public PayStrategy {
public:
    void pay() override {
        cout << "使用微信支付\n";
    }
};

class BankPay : public PayStrategy {
public:
    void pay() override {
        cout << "使用银行卡支付\n";
    }
};

上下文类(持有策略)

class PaymentContext {
private:
    PayStrategy* strategy;
public:
    PaymentContext(PayStrategy* s) : strategy(s) {}
    void setStrategy(PayStrategy* s) { strategy = s; }
    void pay() { strategy->pay(); }
};

使用示例

int main() {
    PayStrategy* alipay = new Alipay();
    PayStrategy* wechat = new WeChatPay();
    PayStrategy* bank = new BankPay();

    PaymentContext context(alipay);
    cout << "第一次支付:\n";
    context.pay();

    cout << "\n切换为微信支付:\n";
    context.setStrategy(wechat);
    context.pay();

    cout << "\n切换为银行卡支付:\n";
    context.setStrategy(bank);
    context.pay();

    delete alipay;
    delete wechat;
    delete bank;

    return 0;
}

六、优缺点

优点

  • 算法封装独立,遵循开闭原则,易于扩展。

  • 消除了多重 if-else,提高代码清晰度。

  • 策略可以在运行时自由切换。

缺点

  • 客户端必须知道有哪些策略,并且主动选择合适的策略。

  • 如果策略类过多,可能增加系统复杂性。

七、应用场景

当系统中需要在运行时切换不同算法或行为。

例如:

排序(快速排序、归并排序等)。

支付方式(支付宝、微信、银行卡)。

日志输出策略(控制台、文件、网络)。

稳定与变化

  • 稳定:PaymentContext 持有 PayStrategy,并调用 pay() 方法。
  • 变化:具体支付方式(支付宝 / 微信 / 银行卡)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值