JAVA中的策略模式详解

server/2024/11/24 23:41:58/

策略模式:让算法选择更灵活

一、引言

在软件开发中,我们经常会遇到需要根据不同情况选择不同的算法来执行任务的场景。如果将这些算法直接硬编码在类中,会导致类的职责过多,不利于维护和扩展。为了解决这个问题,我们可以使用策略模式策略模式定义了一系列的算法,并将每一个算法封装起来,使它们可以互相替换。策略模式使得算法可以独立于使用它的客户端变化。

二、策略模式概述

定义策略模式(Strategy Pattern)定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户。

结构策略模式通常由三个角色组成:

  1. 策略接口(Strategy):这是一个策略族的抽象,通常为接口或抽象类,定义每个策略公有方法的规范。
  2. 具体策略(ConcreteStrategy):实现了策略接口的具体策略类,含有具体的算法。
  3. 上下文(Context):持有一个策略对象的引用,并定义了一个与策略对象的接口相同的接口。客户端通过该接口来调用其所包含的策略对象的算法。

优点

  • 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
  • 简化了算法的切换,使得系统可以很容易地改变行为。
  • 避免了使用多重条件语句(if-else 或 switch-case)。

缺点

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
  • 策略模式造成了很多策略类,增加了系统复杂性。

三、实战演练

假设我们要实现一个简单的计算器,支持加、减、乘、除四种运算。使用策略模式,我们可以为每个运算创建一个具体的策略类。

  1. 定义策略接口
java">public interface Strategy {int doOperation(int num1, int num2);
}
  1. 实现具体策略
java">public class AddStrategy implements Strategy {@Overridepublic int doOperation(int num1, int num2) {return num1 + num2;}
}// 类似地,我们可以创建 SubtractStrategy, MultiplyStrategy, DivideStrategy
  1. 定义上下文
java">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);}
}
  1. 客户端使用
java">public class Client {public static void main(String[] args) {Context context = new Context(new AddStrategy());System.out.println("10 + 5 = " + context.executeStrategy(10, 5));context = new Context(new SubtractStrategy());System.out.println("10 - 5 = " + context.executeStrategy(10, 5));// ...其他运算}
}

四、总结

策略模式是一种非常实用的设计模式,它通过将算法封装成独立的策略类,使得算法的选择更加灵活。当需要扩展新的算法时,只需要增加新的策略类即可,无需修改已有的代码。同时,策略模式也简化了单元测试,因为每个策略类都可以单独进行测试。然而,策略模式也带来了一些复杂性,因为它需要创建多个策略类,并需要客户端知道这些策略类的存在。因此,在使用策略模式时需要根据实际情况进行权衡。


http://www.ppmy.cn/server/51572.html

相关文章

CentOS配置本地yum源

版本说明 操作系统版本:CentOS7.9 虚拟机版本 虚拟机打快照 首先给虚拟机打个快照,点击图下所示位置 命名快照之后,点击拍摄快照 可以参考图下所示进行管理和恢复快照 迁移原有yum源 先进入到/etc/yum.repos.d/ ,可以看到有很多…

Redisson-获取连接原理

归档 GitHub: Redisson-获取连接原理 简介 Redisson 有连接池&#xff0c;获取连接时会从池里面去获取 测试 在 RedissonListTest 加个方法 Testpublic void testGet1() {RList<Integer> list redisson.getList("list", IntegerCodec.INSTANCE);list.add…

如何在Java中实现缓存机制?

如何在Java中实现缓存机制&#xff1f; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将深入探讨在Java应用程序中如何实现高效的缓存机制。缓存是提高…

创建和探索VGG16模型

PyTorch在torchvision库中提供了一组训练好的模型。这些模型大多数接受一个称为 pretrained 的参数&#xff0c;当这个参数为True 时&#xff0c;它会下载为ImageNet 分类问题调整好的权重。让我们看一下创建 VGG16模型的代码片段&#xff1a; from torchvision import models…

docker 删除本地镜像释放磁盘空间

时间一长&#xff0c;本地镜像文件特别多&#xff1a; 1 linux 配置crontab 定期删除 crontab l 查看 crontab e 编辑 30 3 * * * /home/mqq/gengmingming/cleanImage-realize.sh > /home/mqq/gengmingming/cleanImage-realize.log 2>&12 cleanImage-realize.sh …

【消息队列】Kafka学习笔记

概述 定义 传统定义: 一个分布式的, 基于发布订阅模式的消息队列, 主要应用于大数据实时处理领域新定义: 开源的分布式事件流平台, 被用于数据管道/流分析/数据集成 消息队列的使用场景 传统消息队列的主要应用场景包括: 削峰: 解耦: 异步: 两种模式 点对点模式 发布/订…

HTML静态网页成品作业(HTML+CSS)——手机电子商城网页(4个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有4个页面。 二、作品演示 三、代…

HTML|02HTML标签

HTML标签的语义化 语义化就是&#xff1a;标签的含义HTML标签 排版标签标题标签h<h1></h1> 标签有h1-h6&#xff0c;没有h7段落标签p<p></p>水平线标签hr<hr /> 单标记换行标签br<br />div span标签用来布局的 文本格式化标签<b>&…