当前位置: 首页 > news >正文

Spring项目整合策略模式~实战应用

需求背景

1、在管控流程中,涉及到的业务操作很多,不同的业务具有不同的策略实现
举个具体的例子:
在比价管控流程中,有比价策略和管控策略,每个业务的比价和管控均不一样。因此使用策略模式来开发

整体架构流程

1、定义业务策略枚举: 比价 和 管控

/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:33**/
public enum StrategyType {priceCompare,priceControl;
}

2、定义业务策略注解,标注出 策略的类

/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:34**/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = ElementType.TYPE)
@Component
@Inherited
public @interface StrategyAnnotation {/*** 策略类型*/StrategyType[] strategyType();/*** 具体的策略建*/String[] dataType() default {};
}

3、定义策略基本方法

/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:46**/
public interface PriceCompareStrategy {/*** 执行价格比价*/public String doPriceCompare();
}/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:52**/
public interface PriceControlStrategy {/*** 执行管控* @return*/public String doPriceControl();
}

4、写每个具体实现的策略类

/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:44**/
@Service
@StrategyAnnotation(strategyType = StrategyType.priceCompare, dataType = "firstPriceCompare")
public class FirstPriceCompareStrategy implements PriceCompareStrategy {@Overridepublic String doPriceCompare() {System.out.println("-------first price compare start---------");System.out.println("-------do do do ---------");System.out.println("-------first price compare end---------");return "first price compare end";}
}/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:50**/
@Service
@StrategyAnnotation(strategyType = StrategyType.priceCompare, dataType = "secondPriceCompare")
public class SecondPriceCompareStrategy implements PriceCompareStrategy {@Overridepublic String doPriceCompare() {System.out.println("-------second price compare start---------");System.out.println("-------do do do ---------");System.out.println("-------second price compare end---------");return "second price compare end";}
}
/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:53**/
@Service
@StrategyAnnotation(strategyType = StrategyType.priceControl, dataType = "firstPriceControl")
public class FirstPriceControlStrategy implements PriceControlStrategy {@Overridepublic String doPriceControl() {System.out.println("---------do first price control start ---------------");System.out.println("---------do first price control end ---------------");return "do first price control end";}
}/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:53**/
@Service
@StrategyAnnotation(strategyType = StrategyType.priceControl, dataType = "secondPriceControl")
public class SecondPriceControlStrategy implements PriceControlStrategy {@Overridepublic String doPriceControl() {System.out.println("---------do second price control start ---------------");System.out.println("---------do second price control end ---------------");return "do second price control start";}
}@Service
@StrategyAnnotation(strategyType = {StrategyType.priceCompare, StrategyType.priceControl}, dataType = "commonStrategy")
public class PriceCompareAndControlStrategy implements PriceCompareStrategy, PriceControlStrategy {@Overridepublic String doPriceCompare() {System.out.println("-------common price compare start---------------");System.out.println("-------common price compare end---------------");return "common price compare end";}@Overridepublic String doPriceControl() {System.out.println("-------common price control start---------------");System.out.println("-------common price control end---------------");return "common price control end";}
}

5、编写策略管理类,管理所有的策略,并且对外暴露出 拿到具体策略类的方法

package com.dgut.strategy.springboot_strategy;import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;import javax.annotation.PostConstruct;
import java.util.Map;/*** @description:* @author: hongbin.zheng* @create: 2023-07-17 16:59**/
@Service
public class StrategyServiceManager {@Autowiredprivate ApplicationContext context;/*** 存储策略:类型:具体实现类*/private Map<StrategyType, Map<String, Object>> map;public <E> E getStrategyInstance(StrategyType strategyType, String type, Class<E> eClass) {Map<String, Object> strategyTypeMap = map.get(strategyType);if (strategyTypeMap != null && !map.isEmpty()) {Object bean = strategyTypeMap.get(type);if (bean != null) {return eClass.cast(bean);}}return null;}@PostConstructprivate void init() {map = Maps.newHashMap();Map<String, Object> beans = context.getBeansWithAnnotation(StrategyAnnotation.class);for (Object value : beans.values()) {StrategyAnnotation annotation = value.getClass().getAnnotation(StrategyAnnotation.class);StrategyType[] strategyTypes = annotation.strategyType();String[] dataTypes = annotation.dataType();if (strategyTypes == null || strategyTypes.length == 0 || dataTypes == null || dataTypes.length == 0) {throw new RuntimeException("注解上必填字段不能为空");}for (StrategyType strategyType : strategyTypes) {for (String dataType : dataTypes) {map.computeIfAbsent(strategyType, k -> Maps.newHashMap()).put(dataType, value);}}}}}

6、代码流程测试

package com.dgut.strategy.springboot_strategy;import com.dgut.strategy.springboot_strategy.compare.PriceCompareStrategy;
import com.dgut.strategy.springboot_strategy.control.PriceControlStrategy;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;/*** @description:* @author: hongbin.zheng* @create: 2023-07-18 16:17**/
@SpringBootTest
public class StrategyTest {@Autowiredprivate StrategyServiceManager strategyServiceManager;@Testpublic void test2() {String strategyName = "priceControl";String dataType = "firstPriceControl";System.out.println(priceControlTest(strategyName, dataType));String dataType2 = "secondPriceControl";System.out.println(priceControlTest(strategyName, dataType2));String dataType3 = "commonStrategy";System.out.println(priceControlTest(strategyName, dataType3));}public String priceControlTest(String strategyName, String dataType) {StrategyType strategyType = StrategyType.valueOf(strategyName);if (strategyType == null) {return "管控策略不存在";}PriceControlStrategy strategyInstance = strategyServiceManager.getStrategyInstance(strategyType, dataType, PriceControlStrategy.class);if (strategyInstance == null) {return "找不到管控策略";}return strategyInstance.doPriceControl();}@Testpublic void test() {String strategyName = "priceCompare";String dataType = "firstPriceCompare";System.out.println(priceCompareTest(strategyName, dataType));String dataType2 = "secondPriceCompare";System.out.println(priceCompareTest(strategyName, dataType2));String dataType3 = "commonStrategy";System.out.println(priceCompareTest(strategyName, dataType3));}public String priceCompareTest(String strategyName, String dataType) {StrategyType strategyType = StrategyType.valueOf(strategyName);if (strategyType == null) {return "策略不存在";}PriceCompareStrategy strategyInstance = strategyServiceManager.getStrategyInstance(strategyType, dataType, PriceCompareStrategy.class);if (strategyInstance == null) {return "找不到比价策略";}return strategyInstance.doPriceCompare();}
}

技术细节

通过spring的context对象,解析获取类注解,拿到bean,常规操作,这个要学起来,很多地方可以这样子操作呢。

总结

知道的越多,不知道的越多,希望对你有帮助! \color{red}知道的越多,不知道的越多,希望对你有帮助! 知道的越多,不知道的越多,希望对你有帮助!

相关文章:

Spring项目整合策略模式~实战应用

需求背景 1、在管控流程中&#xff0c;涉及到的业务操作很多&#xff0c;不同的业务具有不同的策略实现 举个具体的例子&#xff1a; 在比价管控流程中&#xff0c;有比价策略和管控策略&#xff0c;每个业务的比价和管控均不一样。因此使用策略模式来开发 整体架构流程 1、…...

mybatis PageHelper的坑---记录

记录下&#xff0c;自己新开了一个kotlin的项目从而替换java项目&#xff0c;同时升级了部分组件&#xff0c;包括pageHelper&#xff0c;以往代码里有动态sql的配置 //通过不为null的属性查找数据 val tmpResult: List<Map<String?, Any?>> sqlSessionTemplat…...

uniapp微信小程序下载文件并打开

uni.downloadFile({url: 下载的地址,success(res) {console.log(res)if (res.statusCode 200) {console.log(下载成功);var filePath encodeURI(res.tempFilePath);uni.openDocument({filePath: filePath,fileType: "xlsx",showMenu: true,success: function(res) …...

安卓Intent打开系统进程汇总

1&#xff1a;拨打电话 val uri Uri.parse("tel:10086")val intent Intent(Intent.ACTION_DIAL,uri)startActivity(intent) 2&#xff1a;发送短信 val smsUri Uri.parse("smsto:10086")val intent1 Intent(Intent.ACTION_SENDTO,smsUri)intent1.putE…...

python学习(廖雪峰的官方网站部分,自学笔记)

python学习 廖雪峰的官方网站强烈推荐 字符串 Python提供了ord()函数获取字符的整数表示&#xff0c;chr()函数把编码转换为对应的字符 ord( )先当与把字符转成整形&#xff0c;chr( ) 把编码转化成相应的字符 有些时候&#xff0c;字符串里面的%是一个普通字符怎么办&…...

python题-检查该字符串的括号是否成对出现

给定一个字符串&#xff0c;里边可能包含“()”、"{}"两种括号&#xff0c;请编写程序检查该字符串的括号是否成对出现。 输出&#xff1a; true&#xff1a;代表括号成对出现并且嵌套正确&#xff0c;或字符串无括号字符。 false&#xff1a;未正确使用括号字符。 …...

3ds Max建模教程:模拟布料拖拽撕裂和用剑撕裂两种效果

推荐&#xff1a; NSDT场景编辑器 助你快速搭建可二次开发的3D应用场景 1. 拖拽撕布 步骤 1 打开 3ds Max。 打开 3ds Max 步骤 2 在透视视口中创建平面。保持其长度 后座和宽度后座为 100。 创建平面 步骤 3 转到助手>假人并在 飞机的两侧。 助手>假人 步骤 4 选…...

数据可视化(4)散点图及面积图

1.简单散点图 #散点图 #scatter(x,y) x数据&#xff0c;y数据 x[i for i in range(10)] y[random.randint(1,10) for i in range(10)] plt.scatter(x,y) plt.show()2.散点图分析 #分析广告支出与销售收入相关性 dfcarpd.read_excel(广告支出.xlsx) dfdatapd.read_excel(销售…...

Redis - 数据过期策略

Redis提供了两种数据过期策略 惰性删除 和 定期删除 惰性删除 当某个key过期时&#xff0c;不马上删除&#xff0c;而是在调用时&#xff0c;再判断它是否过期&#xff0c;如果过期再删除它 优点 &#xff1a; 对CPU友好&#xff0c;对于很多用不到的key&#xff0c;不用浪费…...

英文论文(sci)解读复现:基于YOLOv5的自然场景下苹果叶片病害实时检测

对于目标检测算法改进&#xff0c;但是应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读发表高水平学术期刊中的SCI论文&#xff0c;并对…...

【Liux下6818开发板(ARM)】实现简易相册

(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误&#x…...

Kubernetes(K8s)从入门到精通系列之六:K8s的基本概念和术语之存储类

Kubernetes K8s从入门到精通系列之六:K8s的基本概念和术语之存储类 一、存储类二、emptyDir三、hostPath四、公有云Volume五、其他类型的Volume六、动态存储管理一、存储类 存储类的资源对象主要包括: VolumePersistent VolumePVCStorageClass基础的存储类资源对象——Volum…...

Spark-统一内存模型

总结&#xff1a; Spark的内存模型分为4部分&#xff0c;分别是存储内存&#xff0c;计算内存&#xff0c;其他内存&#xff0c;预留内存&#xff1b; 其中存储内存和计算内存可以动态占用&#xff0c;当己方内存不足对方空余则可占用对方的内存&#xff0c;计算内存被存储内…...

类的继承和super关键字的使用(JAVA)

继承 所有的OOP语言都会有三个特征&#xff1a; 封装&#xff08;点击可跳转&#xff09;&#xff1b;继承&#xff1b;多态 为什么会有继承呢&#xff1f;可以先看下面的例子&#xff1a; 上面这两个类中的代码很相似因为它们只有最后一个方法不同其它的都相同&#xff0c;这样…...

BGP属性+选路规则

目录 一&#xff0c;BGP的属性—基础属性 1.PrefVal 2.LocPrf 3、优先本地下一跳 &#xff08;NextHop&#xff09; 4、AS-PATH 5、起源属性 6、MED -多出口鉴别属性 二&#xff0c;BGP选路规则 三&#xff0c;BGP的社团属性 一&#xff0c;BGP的属性—基础…...

类的实例化

类的实例化 class Date { public:void Init(int year, int month, int day){_year year;_month month;_day day;}private:int _year;int _month;int _day; //这只是函数的一个声明并没有定义 };上面是一个类&#xff0c;我们可以把有花括号括起来的叫做一个域&#xff…...

智能提词器有哪些?了解一下这款提词工具

智能提词器有哪些&#xff1f;使用智能提词器可以帮助你更好地准备和交付演讲、报告或其他提词场合。它可以提高你的效率&#xff0c;节省你的时间&#xff0c;并让你更加自信地与听众沟通。另外&#xff0c;智能提词器还可以提供一些有用的功能&#xff0c;如语音识别、智能建…...

oracle 19c rac环境配置firewalld

rac环境ip地址说明 [rootdb1 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.16.100.19 db1 172.16.100.30 …...

Flutter 之Bloc入门指南实现倒计时功能

Flutter Timer By Bloc 前言Stream.periodic实现倒计时定义Bloc状态定义Bloc事件定义Bloc组件定义View层参考资料前言 使用Bloc开发Flutter的项目,其项目结构都很简单明确,需要创建状态,创建事件,创建bloc,创建对应的View。flutter_timer项目来分析下Bloc的使用方法。 通…...

目标识别数据集互相转换——xml、txt、json数据格式互转

VOC数据格式与YOLO数据格式互转 1.VOC数据格式 VOC&#xff08;Visual Object Classes&#xff09;是一个常用的计算机视觉数据集&#xff0c;它主要用于对象检测、分类和分割任务。VOC的标注格式&#xff0c;也被许多其他的数据集采用&#xff0c;因此理解这个数据格式是很重…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...