设计模式5-策略模式(Strategy)

设计模式5-策略模式

简介

策略模式也是属于组件协作 模式一种。现代软件专业分工之后的第一个结果是框架语音应用程序的划分。组建协作模式,通过晚期绑定来实现框架与应用程序之间的松耦合。组件协作是二者之间协作时常用的模式。

目的

在软件构建过程中,某些对象使用的算法可能多种多样。会经常改动。如果将这些算法都编码到对象中,将会使对象变得异常复杂。而且有时候不支持使用的算法也是一个性能负担。如何在运行时根据需要透明的更改对象的算法?将算法与对象本身上进行解耦。策略模式的目的就是避免上述问题。

定义

程序中定义一系列算法。把他们一个个封装起来。并且使他们可互相替换变化该模式使得算法可独立于使用它的客户程序而变化扩展或者进行子类化。

结构

策略模式的结构

策略模式包含以下几个部分:

  1. 策略接口(Strategy Interface):定义所有支持的算法的接口。
  2. 具体策略类(Concrete Strategy Classes):实现策略接口的具体算法。
  3. 上下文类(Context Class):包含一个策略对象的引用,并提供设置和执行策略的方法。

要点

策略模式及其子类为组件提供了一系列可重用的算法。从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换。并且它提供了用条件判断语句以外的另一种选择。消除条件判断语句就是在解耦合。还有许多条件判断语句的代码通常都需要用策略模式去替换原有代码。如果策略模式对象没有实例变量那么各个上下文可以共享同一个策略模式的对象。从而节省对象开销。

举例说明

策略模式(Strategy Pattern)是一种行为设计模式,定义了算法族,并将每个算法封装起来,使它们可以互换。策略模式让算法的变化不会影响到使用算法的客户。

1. 策略接口

cpp 复制代码
class Strategy {
public:
    virtual ~Strategy() {}
    virtual void execute() const = 0;
};

2. 具体策略类

cpp 复制代码
class ConcreteStrategyA : public Strategy {
public:
    void execute() const override {
        std::cout << "ConcreteStrategyA executed" << std::endl;
    }
};

class ConcreteStrategyB : public Strategy {
public:
    void execute() const override {
        std::cout << "ConcreteStrategyB executed" << std::endl;
    }
};

3. 上下文类

cpp 复制代码
class Context {
private:
    Strategy* strategy;

public:
    Context(Strategy* strategy = nullptr) : strategy(strategy) {}

    ~Context() {
        delete strategy;
    }

    void setStrategy(Strategy* newStrategy) {
        delete strategy;
        strategy = newStrategy;
    }

    void executeStrategy() const {
        if (strategy) {
            strategy->execute();
        } else {
            std::cout << "No strategy set" << std::endl;
        }
    }
};

4. 客户端代码

cpp 复制代码
int main() {
    Context context;

    context.setStrategy(new ConcreteStrategyA());
    context.executeStrategy();

    context.setStrategy(new ConcreteStrategyB());
    context.executeStrategy();

    return 0;
}

策略模式的反例

反例展示了没有使用策略模式时的代码,这样的代码往往存在代码重复、维护困难、扩展不便的问题。

没有使用策略模式的代码

cpp 复制代码
class Context {
public:
    enum StrategyType {
        STRATEGY_A,
        STRATEGY_B
    };

    void executeStrategy(StrategyType type) const {
        switch (type) {
        case STRATEGY_A:
            std::cout << "Strategy A executed" << std::endl;
            break;
        case STRATEGY_B:
            std::cout << "Strategy B executed" << std::endl;
            break;
        default:
            std::cout << "No valid strategy selected" << std::endl;
            break;
        }
    }
};

int main() {
    Context context;
    context.executeStrategy(Context::STRATEGY_A);
    context.executeStrategy(Context::STRATEGY_B);

    return 0;
}

对比分析

  • 正例(策略模式)

    • 可扩展性:可以轻松地添加新策略,而无需修改上下文类。
    • 可维护性:每个策略封装在独立的类中,代码更易读、更易维护。
    • 开闭原则:对扩展开放,对修改关闭。
  • 反例(未使用策略模式)

    • 可扩展性差:添加新策略需要修改上下文类的代码。
    • 可维护性差:所有策略代码集中在一个类中,代码量大,维护困难。
    • 违背开闭原则:每次添加新策略都需要修改上下文类,容易引入新的错误。

通过策略模式,代码的灵活性和可维护性显著提高,可以轻松地添加、删除或更改策略,而不影响客户端代码。

相关推荐
禅思院20 小时前
前端请求取消与调度完全指南:从 AbortController 到企业级优先级架构
前端·设计模式·前端框架
小bo波20 小时前
用匿名内部类优雅地计算方法执行时间
java·设计模式·性能测试·模板方法模式·lambda·代码优化·匿名内部类
写代码的小阿帆21 小时前
行为型设计模式之观察者(发布-订阅)模式
设计模式
王_teacher1 天前
23种设计模式全解析(GoF 设计模式)
设计模式·软考·软件设计师·软考中级
阿坤带你走近大数据1 天前
分别介绍下java主流的开发框架、设计模式与对应编程语言的高级特性
java·开发语言·设计模式
geovindu1 天前
go: Coroutines Pattern
开发语言·后端·设计模式·golang·协程模式
Anastasiozzzz1 天前
构建健壮软件系统的基石:深入解析面向对象设计七大原则
开发语言·javascript·设计模式·ecmascript
qq_297574672 天前
设计模式系列文章(基础篇第19篇):中介者模式——封装交互关系,解耦网状依赖
设计模式·交互·中介者模式
AI大法师2 天前
老牌媒体怎么从“出版物更新”走到“品牌系统升级”
大数据·人工智能·设计模式·新媒体运营
野生技术架构师2 天前
Java 23 种设计模式:从踩坑到精通 —— 开篇及系列介绍
java·开发语言·设计模式