设计模式(四)、策略模式

embedded/2024/10/18 23:28:17/

介绍

策略模式定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换。通过使用策略模式,可以在运行时根据需要选择不同的算法,而不需要修改客户端代码。

策略模式通过将算法与使用算法的代码解耦,提供了一种动态选择不同算法的方法。客户端代码不需要知道具体的算法细节,而是通过调用环境类来使用所选择的策略。

策略模式包含以下几个核心角色:

  • 环境(Context):维护一个对策略对象的引用,负责将客户端请求委派给具体的策略对象执行。环境类可以通过依赖注入、简单工厂等方式来获取具体策略对象。
  • 抽象策略(Abstract Strategy):定义了策略对象的公共接口或抽象类,规定了具体策略类必须实现的方法。
  • 具体策略(Concrete Strategy):实现了抽象策略定义的接口或抽象类,包含了具体的算法实现。

 代码实现

第一步:创建接口

public interface Strategy {public int doOperation(int num1, int num2);
}

第二步:创建实现接口的实体类

public class OperationAdd implements Strategy{@Overridepublic int doOperation(int num1, int num2) {return num1 + num2;}
}
public class OperationSubtract implements Strategy{@Overridepublic int doOperation(int num1, int num2) {return num1 - num2;}
}
public class OperationMultiply implements Strategy{@Overridepublic int doOperation(int num1, int num2) {return num1 * num2;}
}

 第三步:创建context类

public class Context {private Strategy strategy;public Context(Strategy strategy){this.strategy = strategy;}public int executeStrategy(int num1, int num2){return strategy.doOperation(num1, num2);}
}

 

第四步:使用 Context 来查看当它改变策略 Strategy 时的行为变化

public class StrategyPatternDemo {public static void main(String[] args) {Context context = new Context(new OperationAdd());    System.out.println("10 + 5 = " + context.executeStrategy(10, 5));context = new Context(new OperationSubtract());      System.out.println("10 - 5 = " + context.executeStrategy(10, 5));context = new Context(new OperationMultiply());    System.out.println("10 * 5 = " + context.executeStrategy(10, 5));}
}

 第五步:输出结果

10 + 5 = 15
10 - 5 = 5
10 * 5 = 50 

优点:

 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。

缺点: 

1、策略类会增多。 2、所有策略类都需要对外暴露。

使用场景:

 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。

2、一个系统需要动态地在几种算法中选择一种。

3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

注意事项

如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

 策略模式和模板方法有什么区别

  • 首先,从定义来看,策略模式定义了一系列的算法,并将每一个算法封装起来,使它们可以相互替换。这样,算法的变化不会影响到使用算法的用户,因为算法被封装在独立的类中,使用算法的用户(即应用层)不会感知到算法已经被替换。而模板方法模式则是定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现。它使得子类可以在不改变算法结构的前提下,重新定义算法的某些步骤。
  • 其次,从适用场景来看策略模式主要适用于多种算法可以互换的情况,比如在处理同一类型问题时,有多种处理方式,仅仅是具体行为有差别,或者需要安全地封装多种同一类型的操作。此外,当同一抽象类有多个子类,而又需要使用if-else或者switch-case来选择具体子类时,策略模式也非常有用。而模板方法模式则更适用于那些一次性实现一个算法的不变部分,并将可变部分留给子类实现的情况。在子类的视角中,公共部分被提取出来,集中到一个公共的父类中,避免了代码的重复。
  • 最后,从对算法的控制权来看,模板方法模式对算法有更多的控制权,它定义了算法的骨架,子类只能在这个骨架的基础上进行修改和扩展。而策略模式则更加灵活,它允许客户根据需要选择和替换算法,对算法的依赖程度较低。

http://www.ppmy.cn/embedded/24032.html

相关文章

SpringBoot整合Mybatis实现多数据源配置

文章目录 I Mybatis1.1 数据库连接相关配置1.2 定义读取文件名1.3 为单个SqlSession动态设置隔离级别1.4 mybatis-plus代码生成器II pagehelper分页2.1 pagehelper配置2.2 使用方法III mybatis-plus多数据源配置IV 数据库连接池4.1 Druid的属性配置4.2 监控配置4.3 展示Druid的…

【算法刷题 | 贪心算法08】4.29(划分字母区间、合并区间)

文章目录 14.划分字母区间14.1题目14.2解法:贪心14.2.1贪心思路14.2.2代码实现 15.合并区间15.1题目15.2解法:贪心15.2.1贪心思路15.2.2代码实现 14.划分字母区间 14.1题目 给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一…

从 MySQL 到 ClickHouse 实时数据同步 —— Debezium + Kafka 表引擎

目录 一、总体架构 二、安装配置 MySQL 主从复制 三、安装配置 ClickHouse 集群 四、安装 JDK 五、安装配置 Zookeeper 集群 六、安装配置 Kafaka 集群 七、安装配置 Debezium-Connector-MySQL 插件 1. 创建插件目录 2. 解压文件到插件目录 3. 配置 Kafka Connector …

LabVIEW专栏七、队列

目录 一、队列范例二、命令簇三、队列应用1.1、并行循环队列1.2、命名队列和匿名队列1.2.1、命名队列1.2.2、匿名队列 1.3、长度为1的队列 队列是一种特殊的线性表,就是队列里的元素都是按照顺序进出。 队列的数据元素又称为队列元素。在队列中插入一个队列元素称为…

Android system — 链接器命名空间共享库配置方法(Android 11后)

Android system — 链接器命名空间共享库配置方法 1. 应用进程1.1 应用进程类加载器的命名空间初始化1.1.1 OpenNativeLibrary1.1.2 LibraryNamespaces::Create 1.2 配置共享库位置 2. native进程2.1 native 命名空间配置初始化2.1.1 android_namespace_t::is_accessible2.1.2 …

WebStack 导航主题优化版

主题下载地址:WebStack 导航主题优化版.zip 修复记录: 1、修复已知BUG 2、修复手机版兼容问题 3、修复打开速度,原版打开速度太慢 4、优化页面代码,删除冗杂多余的CSS JS代码 环境要求 WordPress 4.4WordPress 伪静态PHP 5.…

【Redis 开发】Redis哨兵

哨兵 作用和原理服务状态监控选举新的master 搭建哨兵集群RedisTemplate的哨兵模式 作用和原理 Redis提供了哨兵机制来实现主从集群中的自动故障恢复: 哨兵也是一个集群 监控:会不断检查master和slave是否按预期工作自动故障恢复:如果mast…

QT信号和槽通信机制的使用技巧

文章目录 两种信号槽的连接方式信号和槽函数的关联类型如何避免信号和槽的重复连接优化信号传递链路自动关联的信号和槽函数暂时阻塞信号获取信号发送者对象QT4和QT5信号的差异QT中的信号和槽是一种用于实现对象间通信的机制。这种机制通过信号signal和槽slot的连接,实现了一种…