Spring与设计模式实战之策略模式

Spring与设计模式实战之策略模式

引言

在现代软件开发中,设计模式是解决常见设计问题的有效工具。它们提供了经过验证的解决方案,帮助开发人员构建灵活、可扩展和可维护的系统。本文将探讨策略模式在Spring框架中的应用,并通过实际例子展示如何通过Spring的特性来实现和管理策略模式。

1. 策略模式(Strategy Pattern)的概述

策略模式是一种行为型设计模式,它允许定义一系列算法,并将每个算法封装起来,使它们可以互换。这种模式让算法的变化独立于使用算法的客户。在Java中,策略模式通常通过接口和它们的实现类来实现。

1.1 策略模式的结构

  • 策略接口:声明了所有具体策略类都必须实现的操作。
  • 具体策略类:实现了策略接口,定义了具体的算法。
  • 上下文类:维护一个对策略对象的引用,并在需要时调用策略对象的方法。

2. ApplicationContextAware接口的介绍

在Spring框架中,ApplicationContext是一个非常核心的概念。它代表Spring IoC容器,负责实例化、配置和管理Beans。通过实现ApplicationContextAware接口,Spring Bean可以访问Spring的ApplicationContext,从而获取其他Beans或上下文信息。

2.1 ApplicationContextAware的使用

当一个Bean实现ApplicationContextAware接口时,Spring会在初始化该Bean时自动调用其setApplicationContext方法,并传入ApplicationContext实例。这样,该Bean就可以使用这个上下文来获取其他Beans或与Spring容器交互。

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;@Component
public class MyBean implements ApplicationContextAware {private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) {this.applicationContext = applicationContext;}public void doSomething() {// 使用applicationContext获取其他BeanAnotherBean anotherBean = applicationContext.getBean(AnotherBean.class);anotherBean.performTask();}
}

3. StrategyFactory的设计与实现

StrategyFactory是一个策略工厂类,负责根据业务需求创建和提供策略实例。它使用自定义的@TradeStrategy注解来识别和创建具体的策略类实例。

3.1 自定义注解@TradeStrategy

我们首先定义一个自定义注解@TradeStrategy,用于标注具体的策略类。这个注解可以在运行时通过反射机制进行处理。

import java.lang.annotation.*;@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TradeStrategy {String value();
}

3.2 StrategyFactory的实现

StrategyFactory使用Spring的ApplicationContext来动态地获取所有添加了@TradeStrategy注解的Beans,并根据业务编码获取具体的策略类实例。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;@Component
public class StrategyFactory {@Autowiredprivate ApplicationContext applicationContext;private Map<String, ITradeStrategy> strategyMap = new HashMap<>();@PostConstructpublic void init() {Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(TradeStrategy.class);for (Object bean : beansWithAnnotation.values()) {TradeStrategy tradeStrategy = bean.getClass().getAnnotation(TradeStrategy.class);strategyMap.put(tradeStrategy.value(), (ITradeStrategy) bean);}}public ITradeStrategy getStrategy(String code) {return strategyMap.get(code);}
}

4. TradeStrategyContext的角色

TradeStrategyContext充当策略上下文的角色,提供获取策略实例的方法。它包含一个tradeStrategyMap,用于存储策略枚举和对应的策略实现。

4.1 TradeStrategyContext的实现

TradeStrategyContext依赖于StrategyFactory来获取策略实例,并提供一个统一的方法来执行策略。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class TradeStrategyContext {@Autowiredprivate StrategyFactory strategyFactory;public void executeStrategy(String code) {ITradeStrategy strategy = strategyFactory.getStrategy(code);if (strategy != null) {strategy.process();} else {throw new IllegalArgumentException("No strategy found for code: " + code);}}
}

5. ITradeStrategy接口及其实现

ITradeStrategy是一个策略接口,声明了一个process方法,所有具体策略类都需要实现这个接口。

5.1 ITradeStrategy接口

public interface ITradeStrategy {void process();
}

5.2 具体策略类的实现

以下是几个具体策略类的实现示例:

import org.springframework.stereotype.Component;@TradeStrategy("apply")
@Component
public class ApplyServiceStrategy implements ITradeStrategy {@Overridepublic void process() {System.out.println("Processing apply service strategy");}
}@TradeStrategy("redeem")
@Component
public class RedeemServiceStrategy implements ITradeStrategy {@Overridepublic void process() {System.out.println("Processing redeem service strategy");}
}@TradeStrategy("convert")
@Component
public class CovertServiceStrategy implements ITradeStrategy {@Overridepublic void process() {System.out.println("Processing convert service strategy");}
}@TradeStrategy("withdraw")
@Component
public class WithDrawServiceStrategy implements ITradeStrategy {@Overridepublic void process() {System.out.println("Processing withdraw service strategy");}
}

6. TradeController的设计

TradeController是交易请求的统一入口,提供了一个tradeIndex方法来处理交易请求。它使用TradeStrategyContext来获取并执行相应的策略。

6.1 TradeController的实现

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class TradeController {@Autowiredprivate TradeStrategyContext tradeStrategyContext;@GetMapping("/trade")public String tradeIndex(@RequestParam String code) {tradeStrategyContext.executeStrategy(code);return "Trade executed successfully for strategy: " + code;}
}

7. 策略的动态加载与维护

通过Spring的ApplicationContextStrategyFactory可以动态地获取所有添加了@TradeStrategy注解的Beans,并根据业务编码获取具体的策略类实例。这使得系统在添加新的策略时,只需要添加新的策略类并标注@TradeStrategy注解即可,无需修改现有代码。

8. 策略的扩展性

通过自定义注解和策略工厂,系统可以很容易地添加新的策略,而不需要修改现有的代码,提高了系统的扩展性。例如,当需要添加一个新的交易策略时,只需要创建一个新的策略类并标注@TradeStrategy注解,然后在需要时通过业务编码来调用该策略。

8.1 添加新策略的示例

@TradeStrategy("newStrategy")
@Component
public class NewServiceStrategy implements ITradeStrategy {@Overridepublic void process() {System.out.println("Processing new service strategy");}
}

总结

策略模式在Spring框架中的应用展示了设计模式的强大和灵活性。通过自定义注解和Spring的ApplicationContext,我们可以实现策略的动态管理和扩展。这种方法不仅提高了代码的可维护性,还增强了系统的可扩展性。在实际项目中,合理地应用设计模式和Spring特性,可以显著提升系统的设计质量和开发效率。

附一张基金代销渠道订单处理流程图
在这里插入图片描述

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

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

相关文章

【HarmonyOS】关于鸿蒙消息推送的心得体会 (一)

【HarmonyOS】关于鸿蒙消息推送的心得体会&#xff08;一&#xff09; 前言 这几天调研了鸿蒙消息推送的实现方式&#xff0c;形成了开发设计方案&#xff0c;颇有体会&#xff0c;与各位分享。 虽然没做之前觉得很简单的小功能&#xff0c;貌似只需要和华为服务器通信&…

MyPostMan 迭代文档管理、自动化接口闭环测试工具(自动化测试篇)

MyPostMan 是一款类似 PostMan 的接口请求软件&#xff0c;按照 项目&#xff08;微服务&#xff09;、目录来管理我们的接口&#xff0c;基于迭代来管理我们的接口文档&#xff0c;文档可以导出和通过 url 实时分享&#xff0c;按照迭代编写自动化测试用例&#xff0c;在不同环…

TypeScript 函数类型 (二)

函数类型 函数有两种方式定义 function 关键字来定义函数 function a(){}表达式定义&#xff08;箭头函数的形式&#xff09; const a()>{}函数需要定义类型的有三个地方 入参 和 返回值 以及 函数本身 的类型, 函数本身的类型常用于表达式定义的函数 function sum(a:stri…

【低照度图像增强系列(8)】URetinex-Net算法详解与代码实现(2022|CVPR)

前言 ☀️ 在低照度场景下进行目标检测任务&#xff0c;常存在图像RGB特征信息少、提取特征困难、目标识别和定位精度低等问题&#xff0c;给检测带来一定的难度。 &#x1f33b;使用图像增强模块对原始图像进行画质提升&#xff0c;恢复各类图像信息&#xff0c;再使用目标检…

Word参考文献交叉引用

前言 Word自带交叉引用功能&#xff0c;可在正文位置引用文档内自动编号的段落&#xff0c;同时创建超链接&#xff0c;适用于参考文献的引用。使用此方法对参考文献进行引用后&#xff0c;当参考文献的编号发生变化时&#xff0c;只需要更新域即可与正文中的引用相对应。下文…

实习随笔【实现Json格式化与latex渲染】

【写在前面】在实习中&#xff0c;遇到了如下需求&#xff1a; 待格式化数据大概长这样&#xff0c;里面存在Json乱码以及由$$包裹的公式 目标格式&#xff1a; 一、Json格式化 我们这里的任务主要分为两部分&#xff1a; 解析一个可能包含嵌套的 JSON 字符串格式化 JSON 对象…

这个工具居然能让你的微信暴露得一览无余!!

今天在github看到一个不错的项目&#xff0c;叫做wx-dump-4j&#xff0c;不看不知道&#xff0c;一看吓一跳&#xff0c;这个工具完全的解析了我的微信&#xff01;这个工具准确显示好友数、群聊数和当日消息总量&#xff0c;并且&#xff01;&#xff01;这个工具提供过去15天…

冷却塔的选型计算介绍

1 冷却塔补水量计算 冷却塔补水蒸发量排污量飘散损失泄漏量。一般冷却塔内水份的蒸发量约为进水量的1&#xff5e;2.5%。 &#xff08;1&#xff09;蒸发量 总冷却循环水量的蒸发量E C ① 冷却蒸发量 E E&#xff1d;72Q(X1–X2)&#xff1d;L △t&#xff0f;600 E : 蒸发…

【C++题解】1154. 数组元素的查找

问题&#xff1a;1154. 数组元素的查找 类型&#xff1a;数组找数 题目描述&#xff1a; 给你 m 个整数&#xff0c;查找其中有无值为 n 的数&#xff0c;有则输出该数第一次出现的位置,没有则输出 −1 。 输入&#xff1a; 第一行一个整数 m 代表数的个数 ( 0≤m≤100 ) 。…

数据结构-C语言-排序(2)

代码位置&#xff1a;test-c-2024: 对C语言习题代码的练习 (gitee.com) 一、前言&#xff1a; 1.1-排序定义&#xff1a; 排序就是将一组杂乱无章的数据按照一定的规律&#xff08;升序或降序&#xff09;组织起来。(注&#xff1a;我们这里的排序采用的都为升序) 1.2-排序分…

Ubuntu 22.04.4 LTS (linux) 安装iftop 监控网卡流量 软件

1 安装iftop sudo apt update sudo apt-get install iftop 2 监控网卡 sudo iftop -i eth0 -n -p 界面最上面&#xff0c;显示的是类似刻度尺的刻度范围&#xff0c;显示流量图形的长条作标尺用的。 中间的< >这两个左右箭头&#xff0c;表示的是流量的进出方向.TX&…

SQL Server的视图

SQL Server的视图 一、基础 SQL 视图&#xff08;Views&#xff09;是一种虚拟表&#xff0c;是基于 SQL 查询结果生成的。这些虚拟表可以包含来自一个或多个表的数据&#xff0c;并且可以像表一样查询&#xff1b;视图是一个表中的数据经过某种筛选后的显示方式&#xff0c;或…

3D数字孪生项目运行卡顿,来看看它要求的电脑配置。

有些小伙伴和我说&#xff0c;数字孪生项目运行卡顿&#xff0c;不知道啥原因&#xff0c;根源还是这类项目是浏览器渲染&#xff0c;对电脑配置要求很高。 运行3D数字孪生项目需要一台性能强大的电脑&#xff0c; 以下是一个推荐的配置清单&#xff1a; 1. 处理器&#xff1…

百度人脸识别Windows C++离线sdk C#接入

百度人脸识别Windows C离线sdk C#接入 目录 说明 设计背景 • 场景特点&#xff1a; • 客户特点&#xff1a; • 核心需求&#xff1a; SDK 包结构 效果 代码 说明 自己根据SDK封装了动态库&#xff0c;然后C#调用。 功能接口 设计背景 • 场景特点&#xff1a; -…

中国姓名学大师排行榜,山东济南最有名的起名大师是谁

在2024年揭晓的中国姓名学领域&#xff0c;一场声势浩大的评选活动吸引了无数目光——寻找国内最杰出的起名大师。在这场激烈的竞争中&#xff0c;山东济南的颜廷利教授以其深厚的易学功底和卓越的命名技艺&#xff0c;荣获“中国姓名学十大权威专家”榜首位置&#xff0c;成为…

nftables(7)集合(SETS)

简介 在nftables中&#xff0c;集合&#xff08;sets&#xff09;是一个非常有用的特性&#xff0c;它允许你以集合的形式管理IP地址、端口号等网络元素&#xff0c;从而简化规则的配置和管理。 nftables提供了两种类型的集合&#xff1a;匿名集合和命名集合。 匿名集合&…

php相关

php相关 ​ 借鉴了小迪安全以及各位大佬的博客&#xff0c;如果一切顺利&#xff0c;会不定期更新。 如果感觉不妥&#xff0c;可以私信删除。 默认有php基础。 文章目录 php相关1. php 缺陷函数1. 与2. MD53. intval()4. preg_match() 2. php特性1. php字符串解析特性2. 杂…

注册安全分析报告:OneApm

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

[Vulnhub] digitalworld.local-JOY snmp+ProFTPD权限提升

信息收集 IP AddressOpening Ports192.168.101.150TCP:21,22,25,80,110,139,143,445,465,587,993,995 $ nmap -p- 192.168.101.150 --21,22,25,min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 21/tcp open ftp ProFTPD | ftp-anon: Anonymous FTP logi…

idea中使用maven

默认情况下&#xff0c;idea会自动下载并安装maven&#xff0c;这不便于我们管理。 最好是自行下载maven&#xff0c;然后在idea中指定maven的文件夹路径