「全网最细 + 实战源码案例」设计模式——策略模式

简介: 策略模式(Strategy Pattern)是一种行为型设计模式,用于定义一系列可替换的算法或行为,并将它们封装成独立的类。通过上下文持有策略对象,在运行时动态切换算法,提高代码的可维护性和扩展性。适用于需要动态切换算法、避免条件语句、经常扩展算法或保持算法独立性的场景。优点包括符合开闭原则、运行时切换算法、解耦上下文与策略实现、减少条件判断;缺点是增加类数量和策略切换成本。示例中通过定义抽象策略接口和具体策略类,结合上下文类实现动态算法选择。

核心思想

  • 策略模式(Strategy Pattern)是一种行为型设计模式,用于定义一系列算法或策略,将它们封装成独立的类,并使它们可以相互替换,而不影响客户端的代码,提高代码的可维护性和扩展性。


结构

1. Strategy(抽象策略接口)

  • 定义一些列可供替换的算法方法。

2. ConcreteStrategy(具体策略实现)

  • 实现不同的算法或行为。

3. Context(上下文)

  • 持有策略对象,并在需要时调用具体策略的方法。


适用场景

  1. 动态切换: 想使用不同的算法,并希望在运行时切换。
  2. 避免条件语句(如 if-else switch-case ): 使用策略模式代替这些语句。
  3. 需要经常扩展算法或策略: 新策略的引入只需要实现策略接口并添加到上下文中,而不需要改动现有的算法逻辑。
  4. 算法的独立性: 如果某些算法或操作的实现与具体的上下文和客户端无关,而仅依赖于传入的参数,策略模式能很好地将算法从客户端解耦出来。

优缺点

优点:

  1. 符合开闭原则:无需对 Context 进行修改就能引入新的策略。
  2. 运行时切换:可以在运行时切换对象内的算法。
  3. 解耦: 上下文无需关心具体的策略实现。
  4. 减少 if-else 的使用: 避免大量条件判断,提高可读性和可维护性。

缺点:

  1. 增加类数量:每个策略需要定义一个新的类,可能会类爆炸。
  2. 策略切换成本:客户端必须手动指定策略,无法动态适配。

实现步骤

  1. 从上下文类中找出修改频率较高的算法 (也可能是用于在运行时选择某个算法变体的复杂条件运算符)。
  2. 声明该算法所有变体的通用策略接口。
  3. 将算法逐一抽取到各自的类中, 它们都必须实现策略接口。
  4. 在上下文类中添加一个成员变量用于保存对于策略对象的引用。 然后提供设置器以修改该成员变量。 上下文仅可通过策略接口同策略对象进行交互, 如有需要还可定义一个接口来让策略访问其数据。
  5. 客户端必须将上下文类与相应策略进行关联, 使上下文可以预期的方式完成其主要工作。

示例

// 抽象策略接口
public interface Strategy {
    void show();
}

// 具体策略——A
public class StrategyA implements Strategy{
    @Override
    public void show() {
        System.out.println("具体策略A");
    }
}

// 具体策略——B
public class StrategyB implements Strategy{
    @Override
    public void show() {
        System.out.println("具体策略B");
    }
}

// 具体策略——C
public class StrategyC implements Strategy{
    @Override
    public void show() {
        System.out.println("具体策略C");
    }
}

// 上下文
public class SalesMan {

    // 持有一个抽象策略接口
    private Strategy strategy;

    // 构造方法,传入一个具体策略对象
    public SalesMan(Strategy strategy) {
        this.strategy = strategy;
    }

    // 封装后的策略方法
    public void salesManShow() {
        strategy.show();
    }
}

// 测试类
public class Client {
    public static void main(String[] args) {

        SalesMan salesManA = new SalesMan(new StrategyA());
        salesManA.salesManShow();

        System.out.println("--------------------------------");

        SalesMan salesManB = new SalesMan(new StrategyB());
        salesManB.salesManShow();

        System.out.println("--------------------------------");

        SalesMan salesManC = new SalesMan(new StrategyC());
        salesManC.salesManShow();
    }
}

在源码中的应用


与其他模式的关系

  • 桥接模式状态模式策略模式 (在某种程度上包括适配器模式) 模式的接口非常相似。 实际上, 它们都基于组合模式——即将工作委派给其他对象, 不过也各自解决了不同的问题。 模式并不只是以特定方式组织代码的配方, 你还可以使用它们来和其他开发者讨论模式所解决的问题。
  • 命令模式策略看上去很像, 因为两者都能通过某些行为来参数化对象。 但是, 它们的意图有非常大的不同。
    • 你可以使用 来将任何操作转换为对象。 操作的参数将成为对象的成员变量。 你可以通过转换来延迟操作的执行、 将操作放入队列、 保存历史命令或者向远程服务发送命令等。
    • 另一方面, 通常可用于描述完成某件事的不同方式, 让你能够在同一个上下文类中切换算法。
  • 装饰模式可让你更改对象的外表, 策略则让你能够改变其本质。
  • 模板方法模式基于继承机制: 它允许你通过扩展子类中的部分内容来改变部分算法。 策略基于组合机制: 你可以通过对相应行为提供不同的策略来改变对象的部分行为。 在类层次上运作, 因此它是静态的。 在对象层次上运作, 因此允许在运行时切换行为。
  • 状态可被视为策略的扩展。 两者都基于组合机制: 它们都通过将部分工作委派给 “帮手” 对象来改变其在不同情景下的行为。 策略使得这些对象相互之间完全独立, 它们不知道其他对象的存在。 但状态模式没有限制具体状态之间的依赖, 且允许它们自行改变在不同情景下的状态。
目录
相关文章
|
1月前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
266 35
|
2月前
|
设计模式 人工智能 算法
基于多设计模式的状态扭转设计:策略模式与责任链模式的实战应用
接下来,我会结合实战案例,聊聊如何用「策略模式 + 责任链模式」构建灵活可扩展的状态引擎,让抽奖系统的状态管理从「混乱战场」变成「有序流水线」。
设计模式 存储 人工智能
196 0
|
4月前
|
设计模式 C++
【实战指南】设计模式 - 工厂模式
工厂模式是一种面向对象设计模式,通过定义“工厂”来创建具体产品实例。它包含简单工厂、工厂方法和抽象工厂三种形式,分别适用于不同复杂度的场景。简单工厂便于理解但扩展性差;工厂方法符合开闭原则,适合单一类型产品创建;抽象工厂支持多类型产品创建,但不便于新增产品种类。三者各有优缺点,适用于不同设计需求。
177 53
|
5月前
|
设计模式 存储 缓存
Netty源码—9.性能优化和设计模式
本文主要介绍了Netty的两大性能优化工具、FastThreadLocal的源码和总结、Recycler的设计理念/使用/四个核心组件/初始化/对象获取/对象回收/异线程收割对象和总结,以及Netty设计模式的单例模式和策略模式。
206 53
|
6月前
|
设计模式 算法 Java
设计模式觉醒系列(04)策略模式|简单工厂模式的升级版
本文介绍了简单工厂模式与策略模式的概念及其融合实践。简单工厂模式用于对象创建,通过隐藏实现细节简化代码;策略模式关注行为封装与切换,支持动态替换算法,增强灵活性。两者结合形成“策略工厂”,既简化对象创建又保持低耦合。文章通过支付案例演示了模式的应用,并强调实际开发中应根据需求选择合适的设计模式,避免生搬硬套。最后推荐了JVM调优、并发编程等技术专题,助力开发者提升技能。
|
6月前
|
设计模式 负载均衡 监控
并发设计模式实战系列(2):领导者/追随者模式
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第二章领导者/追随者(Leader/Followers)模式,废话不多说直接开始~
205 0
|
6月前
|
设计模式 监控 Java
并发设计模式实战系列(1):半同步/半异步模式
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第一章半同步/半异步(Half-Sync/Half-Async)模式,废话不多说直接开始~
192 0
|
6月前
|
设计模式 运维 监控
并发设计模式实战系列(4):线程池
需要建立持续的性能剖析(Profiling)和调优机制。通过以上十二个维度的系统化扩展,构建了一个从。设置合理队列容量/拒绝策略。动态扩容/优化任务处理速度。检查线程栈定位热点代码。调整最大用户进程数限制。CPU占用率100%
445 0
|
6月前
|
设计模式 消息中间件 监控
并发设计模式实战系列(3):工作队列
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第三章,废话不多说直接开始~
185 0