当前位置: 首页 > 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;因此理解这个数据格式是很重…...

Linux进程,存储,软件,日志004

目录一、进程管理二、磁盘与存储管理三、软件包管理四、系统日志管理一、进程管理1.1 进程概念与状态进程定义&#xff1a;进程是正在执行的程序实例&#xff0c;包含程序代码、数据和系统资源。进程状态转换&#xff1a;● 运行(RUNNING)&#xff1a;进程正在CPU上执行● 就绪…...

三极管实战指南:从NPN到PNP,手把手教你识别与使用(附常见误区解析)

三极管实战指南&#xff1a;从NPN到PNP&#xff0c;手把手教你识别与使用&#xff08;附常见误区解析&#xff09; 在电子设计的世界里&#xff0c;三极管就像电路中的"水龙头"&#xff0c;控制着电流的流动。无论是简单的LED驱动电路&#xff0c;还是复杂的音频放大…...

告别校园网登录页!实测用UDP 53端口“曲线救国”上网的几种姿势与风险提示

校园网络优化&#xff1a;提升连接效率的合法实践指南 校园网络作为师生日常学习研究的重要基础设施&#xff0c;其稳定性和访问效率直接影响教学科研质量。许多用户在使用过程中会遇到认证页面频繁弹出、连接不稳定等问题&#xff0c;这通常与网络架构设计和流量管理策略有关。…...

ROS Noetic/Melodic下,手把手教你将Qt Designer做的UI打包成Rviz插件

ROS Noetic/Melodic下Qt Designer UI转Rviz插件的完整实践指南 在机器人操作系统&#xff08;ROS&#xff09;生态中&#xff0c;Rviz作为可视化利器&#xff0c;其插件机制允许开发者扩展自定义功能。当遇到需要将Qt Designer设计的精美界面嵌入Rviz时&#xff0c;许多开发者会…...

3个维度解析G-Helper:华硕笔记本性能优化的轻量级解决方案

3个维度解析G-Helper&#xff1a;华硕笔记本性能优化的轻量级解决方案 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目…...

告别Trello!这款开源看板工具让你的团队协作更高效

1. 为什么你需要一个Trello替代品&#xff1f; 如果你正在使用Trello管理团队项目&#xff0c;可能已经发现了一些痛点。Trello确实简单易用&#xff0c;但随着团队规模扩大或项目复杂度增加&#xff0c;免费版的限制就会显现出来。比如最多只能创建10个看板&#xff0c;每个看…...

Arduino蓝牙TPMS解析库:7字节广告数据逆向与嵌入式解码实践

1. BluetoothTPMS 库技术解析&#xff1a;面向嵌入式系统的蓝牙胎压监测数据解码实践1.1 项目定位与工程价值BluetoothTPMS 是一个专为 Arduino 平台设计的轻量级开源库&#xff0c;核心目标是实现对低成本商用 TPMS&#xff08;Tire Pressure Monitoring System&#xff09;传…...

误删Anaconda?4招紧急救援方案

问题背景与常见场景Anaconda被误删可能由误操作、系统崩溃、病毒攻击等原因导致&#xff0c;涉及环境、包、配置等关键数据丢失。抢救前的准备工作立即停止对Anaconda所在磁盘的写入操作&#xff0c;避免数据被覆盖。 确认删除方式&#xff08;回收站、ShiftDelete、格式化等&a…...

别再手动处理工单了!手把手教你用Docker Compose一键部署Ferry工单系统(附避坑指南)

容器化部署Ferry工单系统&#xff1a;10分钟打造高可用生产环境 传统工单系统部署往往需要耗费数小时在环境配置和依赖安装上&#xff0c;而Docker Compose的出现彻底改变了这一局面。想象一下&#xff0c;当你接手一个新项目需要快速搭建工单系统时&#xff0c;不再需要逐行执…...

SigmaStar SSD21X系列芯片:智能家居与工业控制的多场景显示解决方案

1. SigmaStar SSD21X系列芯片&#xff1a;智能家居与工业控制的显示利器 第一次接触SigmaStar SSD21X系列芯片是在一个智能门锁项目上。当时客户要求低成本实现高清彩色触控屏&#xff0c;还要支持人脸识别和远程控制。测试了几款方案后&#xff0c;SSD210的表现让我印象深刻—…...