项目中常见的几种策略模式实现方式

news2024/10/7 14:30:26

前言

  本篇文章主要介绍本人在自己项目中和开源项目中策略模式的实现方式

基于spring实现策略模式

  1. 最近在使用nacos-sync同步工具时发现其使用了策略模式,下面主要介绍它是如何使用的

  2. 实现步骤
    2.1 定义接口:SyncService

    public interface SyncService {
    	boolean sync(TaskDO taskDO);
    }
    

    2.2 多个SyncService接口实现类,下面举例一个ZookeeperSyncToNacosServiceImpl

    // @NacosSyncService注解包含@Component
    @NacosSyncService(sourceCluster = ClusterTypeEnum.ZK, destinationCluster = ClusterTypeEnum.NACOS)
    public class ZookeeperSyncToNacosServiceImpl implements SyncService {
    	 @Override
        public boolean sync(TaskDO taskDO) {
        	// 同步代码忽略   
            return true;
        }
    }
    

    2.3 在SyncManagerService类中进行策略分发

    @Service
    public class SyncManagerService implements InitializingBean, ApplicationContextAware {
    	private ConcurrentHashMap<String, SyncService> syncServiceMap = new ConcurrentHashMap<String, SyncService>();
    	private ApplicationContext applicationContext;
    	
    	// 通过来源和去向为key在syncServiceMap查看对应SyncService进行同步
    	public boolean sync(TaskDO taskDO) {
            return getSyncService(taskDO.getSourceClusterId(), taskDO.getDestClusterId()).sync(taskDO);
        }
    
    	// 从spring容器中查找带NacosSyncService注解的类并放入syncServiceMap中
    	@Override
        public void afterPropertiesSet() {
            this.applicationContext.getBeansOfType(SyncService.class).forEach((key, value) -> {
                NacosSyncService nacosSyncService = value.getClass().getAnnotation(NacosSyncService.class);
                ClusterTypeEnum sourceCluster = nacosSyncService.sourceCluster();
                ClusterTypeEnum destinationCluster = nacosSyncService.destinationCluster();
                syncServiceMap.put(generateSyncKey(sourceCluster, destinationCluster), value);
            });
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    
    	public SyncService getSyncService(String sourceClusterId, String destClusterId) {
            ClusterTypeEnum sourceClusterType = this.skyWalkerCacheServices.getClusterType(sourceClusterId);
            ClusterTypeEnum destClusterType = this.skyWalkerCacheServices.getClusterType(destClusterId);
    
            return syncServiceMap.get(generateSyncKey(sourceClusterType, destClusterType));
        }
    }
    

基于Lambda方式实现

  1. 上面实现需要写很多实现类,如果不想写很多实现类可以考虑用lambda方式实现
  2. 下面展示重要策略分发类:AcoChildCompServiceDispatcher
    @Service
    public class AcoChildCompServiceDispatcher {
    
        private Map<String,BiConsumer<ProjectInfo,ProCode>> handlers = new ConcurrentHashMap<>();
    
        @Resource
        private AcoChildCompService acoChildCompService;
    
    	// 在初始化将策略方法添加到handlers中
        @PostConstruct
        public void init(){
            handlers.put(ComTypeEnum.FRONT.getValue(), acoChildCompService::saveAcoChildInfoByParseWebpackCommon);
            handlers.put(ComTypeEnum.SERVER.getValue(),acoChildCompService::saveAcoChildInfoByParsePom);
        }
    	
    	// 策略分发
        public void dispatcher(ProjectInfo projectInfo, ProCode proCode){
            String comType = proCode.getComType();
            BiConsumer<ProjectInfo,ProCode> consumer = handlers.get(comType);
            consumer.accept(projectInfo,proCode);
        }
    }
    

基于SPI的插件机制

  1. 上面都是要在项目中增加策略实现类,那能不能加载外面策略实现类呢?最近在看nacos的插件机制,下面把其中重要步骤抽取出来
    1.1 整体项目结构如下
    (1)plugin模块定义插件规则
    (2)自定义插件(例如下图的hello-plugin模块)必须实现HelloPluginService接口,然后META-INF/services下插件接口文件中定义对应的实现类
    (3)在plugin-demo-starter模块中通过SPI加载HelloPluginService接口的实现类
    在这里插入图片描述

    1.2 将自定义插件hello-plugin的jar包放在项目的plugin目录下,然后通过-Dloader.path指定其插件包的位置
    在这里插入图片描述
    (1)注意:plugin-demo-starter模块的pom文件,layout为ZIP配置很重要 在这里插入图片描述

  2. 实现步骤
    2.1 定义一个插件模块,定义插件接口(自定义插件必须引入插件包,实现其接口)

    public interface HelloPluginService {
        String helloContent();
    
        String getHelloServiceName();
    }
    

    2.2 自定义插件实现插件接口HelloPluginService,并通过META-INF/services下插件接口文件中定义对应的实现类

    public class TestHelloPluginService implements HelloPluginService {
        public String helloContent() {
            return "Love you";
        }
    
        public String getHelloServiceName() {
            return "test";
        }
    }
    

    在这里插入图片描述
    2.3 在应用模块通过SPI加载HelloPluginService实现类

    @RestController
    @RequestMapping("/demo")
    public class DemoController {
    
        @RequestMapping("/hello")
        public String hello(String name,String helloServiceName){
            Optional<HelloPluginService> helloPluginService =  HelloPluginManager.getInstance().findHelloServiceSpiImpl(helloServiceName);
            if(helloPluginService.isPresent()){
                String content = helloPluginService.get().helloContent();
                return "hello "+name+", "+content;
            }
            return "hello "+name;
        }
    }
    

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

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

相关文章

交叉导轨具体应用在哪些领域?

交叉导轨通过采用缩短了滚柱体的间距的R型滚柱保持器这种独特的滚柱保持机制&#xff0c;使滚柱体的有效接触长度增大&#xff0c;且交叉导轨的安装高度更低&#xff0c;由于是两付导轨平行安装组合成为一套&#xff0c;使得交叉导轨的机台整体性要好于直线导轨&#xff0c;倾覆…

5 分钟教你如何免费用上 GPT-4

今天要分享的就是普通用户&#xff0c;没有 OpenAI 账号&#xff0c;不需要写代码&#xff0c;你依然可以免费体验 GPT-4&#xff0c;当然&#xff0c;会有一些缺点&#xff0c;本篇文章将会手把手教你怎么用上免费版的 GPT-4 以及它的一些限制。 第一步&#xff1a;打开 Stea…

嵌入式软考备考_5 嵌入式程序设计

嵌入式程序设计 开发流程 要想某个功能要用硬件还是软件实现&#xff08;硬件快&#xff0c;但是耗资源&#xff09;&#xff1f;BSP&#xff1f;裸机还是OS&#xff1f; 硬件的设计与实现-》设备驱动软件的设计与实现-》os的选择&#xff0c;移植&#xff0c;api接口函数的…

人工智能(Pytorch)搭建模型5-注意力机制模型的构建与GRU模型融合应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(Pytorch)搭建模型5-注意力机制模型的构建与GRU模型融合应用。注意力机制是一种神经网络模型&#xff0c;在序列到序列的任务中&#xff0c;可以帮助解决输入序列较长时难以获取全局信息的问题。该模型通过…

工具收集 - 键鼠模拟改建

工具收集 - 键鼠模拟&改建 AutoTinyFreeMouseClickerX-Mouse Button Control AutoTiny 官网&#xff1a;https://autotiny.cn AutoTiny软件是一款PC电脑端使用的自动化录制制作软件&#xff0c;不仅能够实现电脑自动化操作&#xff0c;而且可以控制手机实现自动化操作。 A…

uniApp 实现上传功能(七牛云,node获取上传token)

版本&#xff1a;uniAppvue2uview-ui 需求&#xff1a;利用uView_upload组件实现上传功能 难点&#xff1a;兼容性强&#xff0c;支持pc、App、h5&#xff1b; 1.使用leancloud 实现上传(兼容性弱) JS-SDK 只兼容pc、h5&#xff0c;运行到虚拟机上会报错——uniApp问答详情&am…

深度挖掘.c到.exe的整个过程,透过现象看本质

文章目录 程序的翻译环境和执行环境翻译环境编译预编译头文件的包含删除注释替换#define定义的符号 编译词法分析语法分析语义分析符号汇总 汇编 链接合并段表符号表的合并和重定位 执行环境 程序的翻译环境和执行环境 在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境…

【Jenkins】使用java -jar jenkins.war --httpPort=XXXX启动Jenkins报错【解决方案】

使用java -jar jenkins.war --httpPortXXXX启动Jenkins报错【解决方案】 &#x1f449;欢迎关注博主【米码收割机】 &#x1f449;一起学习C、Python主流编程语言。 &#x1f449;机器人、人工智能等相关领域开发技术。 &#x1f449;主流开发、测试技能。 文章目录 使用java -…

学习分享|一文搞懂WiFi 6/7 以及选择路由器改造网络那些事

目录 什么是 WiFi 6 WiFi 6 功能特点 WIFI 6 与前几代对比 速度更快 延时更低 容量更大 更安全 更省电 WiFi 4~WiFi 6对比 WiFi 6 核心技术 WiFi 7 WiFi 世代列表 路由器常用技术扩展 2.5Ge 网口 WAN/LAN口复用/网口盲插 双WAN口 双LAN口端口聚合 mesh组网 聊…

实验四 文件系统原理与模拟实现

实验四 文件系统原理与模拟实现 代码资源地址 Java实现的混合索引和成组链接法算法资源-CSDN文库 实验目的&#xff1a; 了解操作系统中文件系统的结构和管理过程&#xff0c;掌握经典的算法&#xff1a;混合索引与成组链接法等方法。 实验内容&#xff1a; 编程模拟实现混合…

【Android取证篇】ADB版本更新详细步骤

【Android取证篇】ADB版本更新详细步骤 更新ADB版本&#xff0c;解决无法连接设备问题【蘇小沐】 ADB没有自动更新的命令&#xff0c;我们需要下载新的ADB进行替换更新。 1、ADB查找 打开任务管理器&#xff08;快捷键shiftctrlEsc或WinX&#xff09;&#xff0c;在“详细信…

Arcgis通过矢量建筑面找到POI对应的标准地址

背景 有时候我们需要找到POI对应的标准地址,也许有很多的方法, 比如通过POI的地址数据和标准地址做匹配,用sql语句就能实现; 但是POI数据中也存在很多没有地址数据的,这时候只能通过空间关联来匹配对应的标准地址了,而空间关联也有不一样的方法,一个是通过空间连接,找…

数智化转型再加速,低代码开发助力企业转型

毫无疑问&#xff0c;随着数智化转型的加速&#xff0c;越来越多的企业正在把数智化战略提升到一个全新的高度&#xff0c;转型的进程也正从“浅层次”的数智化走向“深层次”数智化的阶段。 据权威机构数据统计&#xff0c;过去几年全球数字经济同比增长15.6%&#xff0c;采取…

DJ5-5/6 与设备无关的 I/O 软件、用户层的 I/O 软件

目录 5.5 与设备无关的 I/O 软件 5.5.1 与设备无关软件的概念 5.5.2 与设备无关的软件的功能 5.5.3 设备分配 5.5.4 逻辑设备名到物理设备名映射的实现 5.6 用户层的 I/O 软件 5.6.1 系统调用与库函数 5.6.2 假脱机技术 SPOOLing 5.5 与设备无关的 I/O 软件 …

鲲鹏昇腾开发者峰会2023举办

[2023年5月6日 广东东莞]今天&#xff0c;以“创未来 享非凡”为主题的鲲鹏昇腾开发者峰会2023在东莞松山湖举办。 鲲鹏产业生态繁荣&#xff0c;稳步发展&#xff0c;正在成为行业核心场景及科研领域首选&#xff0c;加速推动数字化转型&#xff1b;昇腾产业快速蓬勃向上&…

【大数据之Hadoop】二十五、生产调优-HDFS核心参数

1 NameNode内存生产配置 Hadoop3.x系列的NameNode内存是动态分配的&#xff0c;可以用jmap -heap 进程号 查看分配的内存。 在hadoop102中NameNode和DataNode的内存都是自动分配的&#xff0c;且相等。 根据经验&#xff1a; NameNode最小值为1G&#xff0c;每增加1百万个物理…

【JavaEE初阶】多线程带来的风险~线程安全

目录 &#x1f31f;观察线程不安全的现象 &#x1f31f;线程不安全的原因 &#x1f308;1、多个线程修改了同一个共享变量 &#x1f308;2、线程是抢占式执行的&#xff0c;CPU的调度是随机的 &#x1f308;3、指令执行时没有保证原子性 &#x1f308;4、多线程环境中内…

当无触控板和鼠标的情况下,如何开启触控板

背景&#xff1a;一次出行匆忙&#xff0c;忘记带鼠标&#xff0c;周围也无可用工具&#xff0c;主要是触控板当时也被我关闭了&#xff0c;下面讲述一下我是如何解决在没有鼠标的情况下开启触控板的。 首先我们开启电脑后&#xff0c; 存在两种思路去开启触控板 第一种方案…

加拿大访问学者签证材料清单

加拿大在教育、政府透明度、社会自由度以及生活品质等方面在国际上排名名列前茅&#xff0c;出于环境、社会氛围等因素&#xff0c;不少学者将目光聚焦于这个北美的发达国家。加拿大的访问学者签证属于工作签证&#xff0c;过去只要有邀请函就可以办理&#xff0c;但是自去年2月…

Python:Python底层原理:Python的整数是如何实现的

Python整数在底层存储方式 1. Python整数在底层对应的结构体 PyLongObject2.整数是怎么存储的2.1 整数0存储2.2 整数12.3 整数-12.4. 2**30 -12.5 . 2**302.6 . ob_digit[a, b, c] 对应整数计算 计算整数所占内存大小总结 Python的底层是C/C &#xff0c;但是 C/C 能表示的整数…