灵活应对:策略模式在软件设计中的应用

策略模式是一种行为型设计模式,它允许定义一系列算法,并将每个算法封装起来,使它们可以互换使用。策略模式让算法的变化独立于使用算法的客户端,使得在不修改原有代码的情况下切换或扩展新的算法成为可能。

使用策略模式的场景包括但不限于:

当存在多种实现方式,且需要在运行时根据不同条件动态选择具体实现时。例如,一个购物应用可能需要根据用户的会员等级来计算折扣,不同等级对应不同的计算方式,这时就可以使用策略模式来实现。
当存在一组类似的行为,实现细节略有不同,但又不希望通过继承来添加新的子类时。这样可以避免类的爆炸性增长,保持类的单一职责原则。

代码示例

在Java中实现策略模式时,通常会涉及以下几个角色的类和接口,它们之间的关系构成了策略模式的核心:

  1. 上下文(Context):
    维护对策略对象的引用。可定义一个接口来让策略对象访问上下文中的其他数据。
  2. 策略Strategy):
    定义所有支持的算法或行为的策略接口。该接口通常包含一个方法,该方法用于执行策略。
  3. 具体策略(Concrete Strategy):实现策略接口的具体类。每个具体策略类实现算法或行为的一个变体。
  4. 客户端(Client):
    使用上下文和策略接口的类。不直接调用策略方法,而是通过上下文进行。

如下图所示:
在这里插入图片描述

以下是示例的java实现:

// 定义策略接口
interface Strategy {void execute();
}// 实现策略接口的具体策略类A
class ConcreteStrategyA implements Strategy {public void execute() {System.out.println("执行策略A");}
}// 实现策略接口的具体策略类B
class ConcreteStrategyB implements Strategy {public void execute() {System.out.println("执行策略B");}
}// 上下文类,用于维护策略对象
class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public void setStrategy(Strategy strategy) {this.strategy = strategy;}public void executeStrategy() {strategy.execute();}
}// 客户端代码
public class Client {public static void main(String[] args) {// 创建具体策略对象A和BStrategy strategyA = new ConcreteStrategyA();Strategy strategyB = new ConcreteStrategyB();// 创建上下文对象,并设置具体策略对象Context context = new Context(strategyA);// 执行策略context.executeStrategy();// 切换策略context.setStrategy(strategyB);// 再次执行策略context.executeStrategy();}
}

JDK源码中策略模式的应用

Collections.sort() 方法在 JDK中是策略模式的一个经典应用。这个方法根据传入的列表(List)以及可选的比较器(Comparator),对列表进行排序。
使用流程:

  1. 客户端代码调用Collections.sort()方法,并传入自定义比较器。
  2. Collections.sort()方法接收列表作为参数。
  3. 列表返回其元素给Collections.sort()方法以进行比较。
  4. Collections.sort()方法使用自定义比较器(如果提供)或元素的自然顺序(如果元素实现了Comparable接口)来确定排序逻辑。
  5. 根据选择的策略,Collections.sort()方法对列表进行排序。
    如图所示:
    在这里插入图片描述

以下是 Collections.sort() 方法的策略模式分析:

  1. 策略接口:这里的策略接口是 Comparator,它定义了排序策略的公共行为,即 compare(Object o1, Object o2) 方法。Comparator 可以有多个实现,每个实现提供不同的排序规则。

  2. 具体策略:Comparator 的实现类代表具体策略。例如,Collections.reverseOrder() 返回一个反向排序的比较器,而 Collections.naturalOrder() 返回自然顺序的比较器。用户也可以自定义 Comparator 来表达特定的排序需求。

  3. 上下文(Context):Collections.sort() 方法本身充当上下文角色。它接受一个列表和一个可选的比较器对象。如果提供了比较器,Collections.sort() 会使用该比较器来对列表元素进行排序;如果没有提供,它会使用元素类型的自然顺序(如果元素类型实现了 Comparable 接口)。

  4. 策略的使用:在 Collections.sort() 内部,默认情况下,如果列表元素实现了 Comparable 接口,并且没有提供比较器,那么排序算法将使用 Comparable 接口提供的 compareTo() 方法作为排序策略。如果提供了 Comparator,则使用该比较器的 compare() 方法。

  5. 策略的切换:由于 Collections.sort() 能够接受不同的 Comparator 实现,因此可以在运行时动态地改变排序策略,无需修改排序代码本身。

  6. 算法的独立性:Collections.sort() 方法内部使用了归并排序或者TimSort(Java 7 引入),这个算法独立于策略。策略模式使得算法可以独立于具体的策略实现,增加了代码的灵活性和可扩展性。

优点

  1. 封装性:策略模式通过将算法封装在独立的策略类中,实现了算法与使用算法的客户端之间的解耦,提高了代码的模块性。
  2. 可扩展性:新的策略可以很容易地被添加进系统,符合开闭原则,即对扩展开放,对修改封闭。
  3. 动态替换:可以在运行时根据不同情况选择不同的算法策略,增加了系统的灵活性。
  4. 避免使用多重条件转移:策略模式提供了用组合来替代继承和庞大的条件语句的新思路,有利于代码的维护和理解。

缺点

  1. 系统复杂度:由于策略模式需要定义一系列的策略类,这会增加系统的复杂度。
  2. 数量增多引发的复杂性:随着策略数量的增加,客户端需要进行更多的策略选择和管理,这可能会引入额外的复杂性。
  3. 可能违反单一职责原则:如果策略类承担了过多的职责,或者某些策略实现过于复杂,可能会违背单一职责原则。
    总的来说,策略模式有助于避免使用多重条件语句,随着策略类数量的增长,管理这些策略可能会变得复杂,且在某些情况下可能违反设计原则。因此,在应用策略模式时,应该权衡其带来的灵活性和解耦优势以及可能引入的复杂性和设计问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/667495.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android inset 管理

目录 简介 Insets管理架构 Insets相关类图 app侧的类 WMS侧的类 inset show的流程 接口 流程 WMS侧确定InsetsSourceControl的流程 两个问题 窗口显示时不改变现有的inset状态 全屏窗口上的dialog 不显示statusbar问题 View 和 DecorView 设置insets信息 输入法显…

幻兽帕鲁客户端存档文件 - 云上备份和恢复教程

本文将详细介绍如何将幻兽帕鲁游戏客户端的存档文件备份至云端,以及如何从云端恢复存档数据至本地。 一、游戏存档备份场景 幻兽帕鲁的游戏进度存储在电脑本地磁盘上,游戏中创建的每个世界都对应一个本地存档文件夹。在玩游戏过程中,客户端…

智能边缘计算网关实现高效数据处理与实时响应-天拓四方

在当今时代,数据已经成为驱动业务决策的关键因素。然而,传统的数据处理方式往往存在延迟,无法满足实时性要求。此时,智能边缘计算网关应运而生,它能够将数据处理和分析的能力从中心服务器转移至设备边缘,大…

基于单片机控制的智能门锁设计

摘要:阐述基于STC15F2K60S2单片机控制的智能门锁设计,包括CPU控制单元模块、液晶显示LCD、 Wi-Fi模块,实现远程控制开门,密码开门的智能化功能。 关键词:控制技术,单片机,智能门锁,…

游戏视频录制软件推荐,打造专业电竞视频(3款)

随着游戏产业的快速发展,越来越多的玩家开始关注游戏视频录制软件。一款好的录制软件不仅可以帮助玩家记录游戏中的精彩瞬间,还可以让其与他人分享自己的游戏体验。接下来,我们将介绍三款热门的游戏视频录制软件,并对其进行详细的…

收放卷转动线速度计算FC(SCL+梯形图代码)

这篇博客是收放控制算法的基础系列,通过这篇文章的学习。大家能更好的理解收放卷控制里的前馈量计算,收放卷前馈PID大家可以参考下面链接文章: https://rxxw-control.blog.csdn.net/article/details/129352629https://rxxw-control.blog.csdn.net/article/details/12935262…

3D Line Mapping Revisited论文阅读

1. 代码地址 GitHub - cvg/limap: A toolbox for mapping and localization with line features. 2. 项目主页 3D Line Mapping Revisited 3. 摘要 提出了一种基于线的重建算法,Limap,可以从多视图图像中构建3D线地图,通过线三角化、精心…

06、全文检索 -- Solr -- Solr 全文检索之在图形界面管理 Core 的 Schema(演示对 普通字段、动态字段、拷贝字段 的添加和删除)

目录 Solr 全文检索之管理 Schema使用Web控制台管理Core的Schema3 种 字段解释:Field:普通字段Dynamic Field:动态字段Copy Field:拷贝字段 演示:添加 普通字段( Field )演示:添加 动…

C++入门的基础

幸福比傲慢更容易蒙住人的眼睛。 ——大仲马 C入门 1、属于C的关键字1、1、C从何而来1、2、C关键字(C98) 2、命名空间2、1、命名空间的定义2、2、命名空间使用 3、C输入和输出4、缺省参数4、1、缺省参数概念4、2、缺省参数分类 5、函数重载5、1、函数重载概念 6、引用6、1、引用…

电脑/机顶盒/ps3/4/连接老电视(只有AV、S-Video接口)解决方案之HDMI转AV/S-Video转换器HAV

HDMI转AV/S-Video转换器功能 01、将HDMI高清信号经过视频处理转换成AV、S-VIDEO(PAL/NTSC)的视频信号输出 02、将HDMI数字音频,经过DAC数模芯片处理转成模拟立体声输出 03、采用先进的视频处理技术,对图像的亮度,对比度及色彩进行增强处理 04…

使用Docker本地部署Jupyter Notebook并结合内网穿透实现远程访问

文章目录 1. 选择与拉取镜像2. 创建容器3. 访问Jupyter工作台4. 远程访问Jupyter工作台4.1 内网穿透工具安装4.2 创建远程连接公网地址4.3 使用固定二级子域名地址远程访问 本文主要介绍如何在Ubuntu系统中使用Docker本地部署Jupyter Notebook,并结合cpolar内网穿透…

01-操作系统_名词_文件下载_反弹

操作系统_名词_文件下载_反弹 一、渗透测试1.1、POC、EXP、Payload与Shellcode1.2、后门1.3、木马1.4、反弹1.5、回显1.6、跳板1.7、黑白盒测试1.8、暴力破解1.9、社会工程学1.10、撞库1.11、ATT&CK 二、案例演示2.1、基础案例1:操作系统-用途&命令&权限…

Android学习之路(27) ProGuard,混淆,R8优化

前言 使用java编写的源代码编译后生成了对于的class文件,但是class文件是一个非常标准的文件,市面上很多软件都可以对class文件进行反编译,为了我们app的安全性,就需要使用到Android代码混淆这一功能。 针对 Java 的混淆&#x…

【Docker】Docker Registry(镜像仓库)

文章目录 一、什么是 Docker Registry二、镜像仓库分类三、镜像仓库工作机制四、常用的镜像仓库五、常用命令镜像仓库命令镜像命令(部分)容器命令(部分) 六、docker镜像仓库实战综合实战一:搭建一个 nginx 服务综合实战二:Docker hub上创建自己私有仓库综…

B站课程评分

Spring6 https://www.bilibili.com/video/BV1Ft4y1g7Fb/ 评价: 推荐一看 配套文档优秀, 老师口齿清晰, 条理不错. mybatis https://www.bilibili.com/video/BV1JP4y1Z73S/?spm_id_from333.337.search-card.all.click 评价: 推荐一看 配套文档优秀, 老师口齿清晰, 条理不错…

等变和不变 、向量神经元(vector neurons)是什么?

等变和不变 等变:如果输入是一个旋转后的椅子,那么输出也应该是一个旋转后的椅子 不变:如果输入是一个旋转后的椅子,那么输出应该是一个椅子,而不是一只狗。 向量神经元(vector neurons) 向量…

如何监控摄像头是否在线?有什么工具推荐

WGCLOUD监控系统 我们项目中,摄像头用的WGCLOUD监控系统来监控的,主要两种方式来监控 一种是监控摄像头的端口,使用WGCLOUD的端口监控模块 一种是PING摄像头的IP,使用WGCLOUD的ping监测模块 这两种方式比较简单,也…

1997-2022年中央对各省份一般公共预算转移支付数据

1997-2022年中央对各省份一般公共预算转移支付数据 1、时间:1997-2022年 2、范围:31省 3、指标:一般公共预算转移支付 4、来源:wind 财政部 5、指标解释:一般性转移支付又称体制性转移支付,是指上级政…

【2024.2.4练习】国王游戏

题目描述 题目思路 涉及排列组合求最优解问题,数据大考虑是否满足某种贪心策略。 假设不除以右手的数字,那么获得金币数量最多的显然为最后一个人。左手数字最大的应排在最后一位。在右手有数字的情况下,不妨也尝试从最后一个人开始排。 假…

Element UI+Spring Boot进行CRUD的实例

ElementUI安装与使用指南 前端代码:点击查看learnelementuispringboot项目源码 后端代码:点击查看 LearnElementUiAndSpringBoot 一、前端配置 安装axios axios官网axios中文文档安装指令:npm install axios 二、后端配置 springboot3m…