常用设计模式——策略模式
策略模式是什么
策略模式(Strategy):针对一组算法,将每一个算法封装起来,从而使得它们可以相互替换。
比如我们一个软件的会员等级,每一个等级都会有对应的一些等级权益,那么每一个等级权益就对应一个策略
结构
策略模式的通用类图如下:
策略模式主要由这三个角色组成,环境角色(Context)、抽象策略角色(Strategy)和具体策略角色(ConcreteStrategy)
1.上下文角色(Context):持有所有策略类的对象,可以根据策略提供相应的算法给客户端使用。
2.抽象策略角色(Strategy):这是一个抽象角色,通常由一个接口或抽象类实现。此角色提供具体策略类所需的接口。
3.具体策略角色(ConcreteStrategy):继承或实现了抽象策略,封装了相应的算法或行为。
策略模式的优缺点
优点
(1)算法可以自由切换
(2)避免使用多重条件判断
(3)扩展性良好,增加一个策略只需实现接口即可
缺点
(1)策略类数量会增多,每个策略都是一个类,复用性很小
(2)所有的策略类都需要对外暴露
使用场景
1、业务代码需要根据场景不同,切换不同的实现逻辑
2、代码中存在大量 if else 逻辑判断
实例
下面使用策略模式实现会员不同等级的权益领取
抽象策略角色:
/*** 会员抽象策略*/
public interface MemberStrategy {/*** 领取会员福利*/void getWeal();}
具体策略角色:
/*** 等级1的会员福利*/
@Component
public class LV1MemberWeal implements MemberStrategy {@Overridepublic void getWeal() {System.out.println("5元优惠券");}}/*** 等级2会员福利*/
@Component
public class LV2MemberWeal implements MemberStrategy{@Overridepublic void getWeal() {System.out.println("10元优惠券");}}
上下文角色:
我们可以使用枚举加bean工厂来定义一个上下文角色,避免上下文角色的if-else
策略枚举类
策略枚举类用于获取bean容器中的策略类class
/*** 策略枚举*/
public enum MemberEnum {LV1(LV1MemberWeal.class),LV2(LV2MemberWeal.class);;private Class clazz;MemberEnum(Class clazz) {this.clazz = clazz;}public static Class getStrategyClass(String name){return MemberEnum.valueOf(name).clazz;}}
使用ApplicationContext可以获取bean工厂中的实例,下面是对应工具类
@Component
public class ApplicationContextUtil implements ApplicationContextAware {private static ApplicationContext applicationContext;/*** 将ApplicationContext注入* @param applicationContext* @throws BeansException*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}public static ApplicationContext getApplicationContext(){return applicationContext;}/*** 根据类型获取bean* @param clazz* @param <T>* @return*/public static <T> T getBean(Class clazz){return (T) getApplicationContext().getBean(clazz);}/*** 根据名称获取bean* @param name* @param <T>* @return*/public static <T> T getBean(String name){return (T) getApplicationContext().getBean(name);}}
上下文角色类
/*** 会员上下文角色*/
@Component
public class MemberStrategyContext {/*** 根据入参类型获取对应的策略类* @param type* @return*/public MemberStrategy getMemberStrategy(String type){MemberStrategy memberStrategy = ApplicationContextUtil.getBean(MemberEnum.getStrategyClass(type));return memberStrategy;}}
测试类
RunWith(SpringRunner.class) //作用:让当前类在容器环境下进行测试
@SpringBootTest(classes = DemoApplication.class)
public class StrategyTest {@Autowiredprivate MemberStrategyContext memberStrategyContext;@Testpublic void testStrategy(){//根据入参获取对应策略类MemberStrategy memberStrategy = memberStrategyContext.getMemberStrategy("LV2");//执行策略类的算法memberStrategy.getWeal();}}
相关文章:

常用设计模式——策略模式
策略模式是什么 策略模式(Strategy):针对一组算法,将每一个算法封装起来,从而使得它们可以相互替换。 比如我们一个软件的会员等级,每一个等级都会有对应的一些等级权益,那么每一个等级权益就…...
牛客网 CM11.链表分割
目录 1.解题思路2.代码实现 1.解题思路 此题目思路相对简单,利用双指针,一个指针指向小于val的,一个指针指向大于等于val的,但实现起来,如果仅仅使用单链表,那么还需特别判断第一个指针是否为空从而特意做…...

[iOS开发]iOS中TabBar中间按钮凸起的实现
在日常使用app的过程中,经常能看到人家实现了底部分栏控制器的中间按钮凸起的效果,那么这是怎么实现的呢? 效果演示: 实现原理: 创建按钮 创建一个UITabBar的子类,重写它的layoutSubviews方法࿱…...

数字时代,企业的数据共享意味着什么?
随着数字化整体在社会方方面面的推进,通过数据直接或间接创造的价值越来越大,逐渐成为了构建现代社会的重要要素。而对于企业来说,数据也是在数字经济中容易接触也切实能够利用产生大量价值,所以如何最大化利用数据,让…...

壹[1],QT自定义控件创建(QtDesigner)
1,环境 Qt 5.14.2 VS2022 原因:厌烦了控件提升的繁琐设置,且看不到界面预览显示。 2,QT制作自定义控件 2.1,New/其他项目/Qt4 设计师自定义控件 2.2,设置项目名称 2.3,设置 2.4,设…...
解决Java对接LDAP AD域登录出现Unprocessed Continuation Reference(s)错误
出现该错误的原因,主要是因为Java namingx的库,默认选项是未设置跟随,389返回的是AD域条目的引用,需要进行引用跟随。 解决方法分为两种,第一类不使用全局目录服务的端口389和636,而是使用真实端口 把代码…...
could not read ok from ADB Server
执行adb devices提示 List of devices attached * daemon not running; starting now at tcp:5037 could not read ok from ADB Server * failed to start daemon 方法1,关闭防火墙, could not read ok from ADB Server_夜星辰2023的博客-CSDN博客 我…...

超越基础:Flutter 中 onTap 的 5 条规则让你脱颖而出
小事情决定了你的熟练程度,这些小细节的有趣之处在于它们的丰富性。您将在代码库中的数百个位置遇到 onTap 事件。增强它们可以对代码的可维护性和最终用户体验产生重大的积极影响。 onTap 就是这样一个微小但丰富的东西——我们在每个屏幕上都使用它。这纯粹是关于…...

综合布线可视化管理系统价值分析
传统综合布线管理,全部依靠手工登记,利用标签标示线缆,利用文档资料记录链路的连接和变更,高度依赖网络管理员的管理能力,维护效率低下。同时,网络接入故障和非法接入难以及时发现。在以往的文章中小编一直…...

【JavaSE】基础笔记 - 类和对象(上)
目录 1、面向对象的初步认知 1.1、什么是面向对象 1.2、面向对象与面向过程 2. 类定义和使用 2.1、简单认识类 2.2、类的定义格式 2.3、自定义类举例说明 2.3.1、定义一个狗类 2.3.2、定义一个学生类 3、类的实例化 3.1、什么是实例化 3.2、类和对象的说明 1、面向…...

浅谈开口互感器在越南美的工业云系统中的应用
摘 要:分析低压开口式电流互感器的原理,结合工程实例分析开口电流互感器在低压配电系统中,主要是改造项目中的应用及施工细节,为用户快速实现智能配电提供解决方案,该方案具有成本低、投资少、安装接线简便等优点&…...
docker的使用以及注意事项
ssh的登录 1.登录ssh ssh 用户名IP地址 2.生成密钥 ssh-keygen生成密钥,在.ssh文件夹中(如果没有自己生成一个) 如果密钥之前已经生成过,可能在配置git的时候,会报错:这个密钥已经使用过的报错 解决方法是:otherwise[…...
大数据之LibrA数据库系统告警处理(ALM-12027 主机PID使用率超过阈值)
告警解释 系统每30秒周期性检测PID使用率,并把实际PID使用率和阈值进行比较,PID使用率默认提供一个阈值。当检测到PID使用率超出阈值时产生该告警。 平滑次数为1,主机PID使用率小于或等于阈值时,告警恢复;平滑次数大…...
软考 系统架构设计师系列知识点之数字孪生体(3)
接前一篇文章:软考 系统架构设计师系列知识点之数字孪生体(2) 所属章节: 第11章. 未来信息综合技术 第5节. 数字孪生体技术概述 3. 数字孪生体的关键技术 建模、仿真和基于数据融合的数字线程是数字孪生体的三项核心技术。能够做…...

新闻稿的写作注意事项!纯干货
新闻稿是企业、机构、政府等组织向公众传递信息的重要途径之一,也是媒体获取新闻素材的主要来源。一篇优质的新聞稿不仅可以吸引读者的注意力,还可以提高组织的形象和声誉。因此写好新闻稿至关重要。下面伯乐网络传媒来给大家探讨一些新闻稿写作的注意事…...

Android开发知识学习——从Retrofit原理来看HTTP
文章目录 Retrofit 使用方法简介Retrofit 源码结构总结扔物线读源码的思路与方式 Retrofit 使用方法简介 导包 implementation com.squareup.retrofit2:retrofit:最新版本创建一个 interface 作为 Web Service 的请求集合,在里面用注解 (Annotation&…...

计算机毕设 基于大数据的抖音短视频数据分析与可视化 - python 大数据 可视化
文章目录 0 前言1 课题背景2 数据清洗3 数据可视化地区-用户观看时间分界线每周观看观看路径发布地点视频时长整体点赞、完播 4 进阶分析相关性分析留存率 5 深度分析客户价值判断 5 最后 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,…...
1.OpenResty系列之入门简介
OpenResty(也称为ngx_openresty)是一个基于Nginx的全功能Web应用服务器,它将Nginx与一组附加模块和Lua脚本语言集成在一起,以提供高性能的Web应用程序开发和扩展性。 Nginx是一个轻量级的、高性能的HTTP服务器和反向代理服务器&a…...
Trie树(字典树)
原理: 1. ch[p][j]:p是每个单词存到的idx索引,j是存入字符映射的数字 2. cnt[p] 存这个单词个数 【模板】字典树 - 洛谷 #include <iostream> #include <cstring> using namespace std;const int N 3e6 10; int ch[N][100], idx; int cnt…...
华为政企网络安全产品集
产品类型产品型号产品说明 防火墙及应用安全网关ASG5505ASG5000系列上网行为管理产品(以下简称“ASG5000”)是华为面向各类企业、政府、大中型数据中心以及各类无线非经营性场所推出的业界领先的综合上网行为管理产品。 该系列产品可深度识别、管控和…...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...