实战讲解,原来是用 SpringBoot 实现策略模式可以这么简单

一、介绍

一说起策略设计模式,相比大家都不陌生,在实际的业务开发中,合理地使用设计模式来编程,可以让代码阅读起来层次感更强,同时扩展性也会得到提升!

最近看同事的代码的时候,学到了一个小技巧,在某些场景下合理地使用策略模式还是非常有用的,在此分享一下给大家。

二、代码实践

在介绍 SpringBoot 在如何实现策略设计模式之前,我们先简单地回顾一下策略模式的设计思路

以编写一个简单的程序计算器,代码如下!

  • 首先,我们定义一个Operation接口,用于逻辑的计算

public interface Operation { /** * 执行计算 * @param a * @param b * @return */ int execute(int a, int b);}

  • 接着,分别将四个if判断逻辑独立成一个模块,来单独处理

public class AddOperation implements Operation { @Override public int execute(int a, int b) { return a + b; }}public class SubOperation implements Operation { @Override public int execute(int a, int b) { return a – b; }}public class MultiOperation implements Operation { @Override public int execute(int a, int b) { return a * b; }}public class DivOperation implements Operation { @Override public int execute(int a, int b) { return a / b; }}

  • 然后,创建一个工厂类,用于处理客户端传入的参数

public class OperatorFactory { private static Map operationMap = new HashMap(); static { //初始化实现类 operationMap.put(“add”, new AddOperation()); operationMap.put(“sub”, new SubOperation()); operationMap.put(“multi”, new MultiOperation()); operationMap.put(“p”, new DivOperation()); // more operators } /** * 获取对应的目标实现类 * @param operator * @return */ public static Optional getOperation(String operator){ return Optional.ofNullable(operationMap.get(operator)); }}

  • 最后,在需要的地方引入方法即可!

public class OperatorTestMain { public static void main(String[] args) { //获取计算的目标实现类 Operation targetOperation = OperatorFactory .getOperation(“add”) .orElseThrow(() -> new IllegalArgumentException(“Invalid Operator”)); int result = targetOperation.execute(1, 2); System.out.println(“result:” + result); }}

以上就是一个典型的策略模式的实践思路,从代码阅读性、扩展性角度看,还是非常干净利落的。

那么,在SpringBoot项目中,我们应该如何使用呢?

三、SpringBoot 实践应用

3.1、方案

  • 首先,我们还是定义一个Command接口,用于方法的抽象和统一

public interface Command { /** * 命令类型 * @return */ String operateType(); /** * 执行 * @param a * @param b * @return */ Integer execute(int a, int b);}

  • 接着,编写四套不同的计算处理逻辑

@Componentpublic class AddCommand implements Command { @Override public String operateType() { return “add”; } @Override public Integer execute(int a, int b) { return a + b; }}@Componentpublic class SubCommand implements Command { @Override public String operateType() { return “subtract”; } @Override public Integer execute(int a, int b) { return a – b; }}@Componentpublic class MultiCommand implements Command { @Override public String operateType() { return “multiply”; } @Override public Integer execute(int a, int b) { return a * b; }}@Componentpublic class DivCommand implements Command { @Override public String operateType() { return “pide”; } @Override public Integer execute(int a, int b) { return a / b; }}

  • 然后,编写一个类似于上文的策略处理类

@Componentpublic class CalculatorService implements ApplicationContextAware { private Map commandMap = new ConcurrentHashMap(); /** * 执行计算 * @param operateType * @param a * @param b * @return */ public int calculate(String operateType,int a, int b){ Command targetCommand = Optional.ofNullable(commandMap.get(operateType)) .orElseThrow(() -> new IllegalArgumentException(“Invalid Operator”)); return targetCommand.execute(a,b); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { Map tempMap = applicationContext.getBeansOfType(Command.class); tempMap.values().forEach(source -> commandMap.put(source.operateType(), source)); }}

  • 最后,我们只需要在适当的位置应用即可!

@RunWith(SpringRunner.class)@SpringBootTestpublic class CalculatorServiceTest { @Autowired private CalculatorService calculatorService; @Test public void test(){ int result = calculatorService.calculate(“add”, 1,2); System.out.println(“result:” + result); }}

总结:这种方案的实践,和上面介绍的思路基本上一致,不同的地方在于,当 springboot 启动时,会将对象注入到IOC容器。

3.2、方案二(推荐)

翻查Spring的ioc容器,你会发现一个秘密,当一个接口有多个实现类时,Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id,value值则为对应的策略实现类。

简单的说,我们只需要通过@Autowired注入对象,不需要通过CalculatorService这个类进行单独配置,操作方式如下!

  • 首先,编写一个CommandFactory工厂类,用于逻辑的处理

@Componentpublic class CommandFactory { /** * Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id,value值则为对应的策略实现类 */ @Autowired private Map commandMap; /** * 执行计算 * @param operateType * @param a * @param b * @return */ public int calculate(String operateType,int a, int b){ Command targetCommand = Optional.ofNullable(commandMap.get(operateType)) .orElseThrow(() -> new IllegalArgumentException(“Invalid Operator”)); return targetCommand.execute(a,b); }}

  • 最后,直接在合适的地方使用CommandFactory即可!

@RunWith(SpringRunner.class)@SpringBootTestpublic class CalculatorServiceTest { @Autowired private CommandFactory commandFactory; @Test public void test(){ int result = commandFactory.calculate(“addCommand”, 1,2); System.out.println(“result:” + result); }}

总结:方案二和方案一的不同点在于,不需要显式的编写CalculatorService策略处理类来初始化对象,Spring在初始化对象的时候,可以帮忙我们实现对象的注入!

四、小结

本文主要围绕在 SpringBoot 引入策略模式的设计思路和实践方法进行介绍,在实际的业务开发中,合理地使用策略模式,能让代码看起来更加清爽,业务扩展性也更佳强大,希望能帮助到大家!

郑重声明:本文内容及图片均整理自互联网,不代表本站立场,版权归原作者所有,如有侵权请联系管理员(admin#wlmqw.com)删除。
(0)
用户投稿
上一篇 2022年6月20日
下一篇 2022年6月20日

相关推荐

  • 史上最强vue总结,面试开发全靠它了

    vue框架篇 vue的优点 轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb; 简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习; 双向数据绑定:…

    2022年8月6日
  • 56胜26负!灰熊常规赛位列西部第二,将贝恩和3J视为球队未来核心

    最近有消息称,西部强队灰熊最近也加入了对杜兰特的争夺。据媒体消息,灰熊以亚当斯、安德森、琼斯、布鲁克斯和梅尔顿加5个首轮选秀权为筹码向篮网提出了报价。不得不说灰熊的报价是所有给篮网…

    2022年8月25日
  • 问界M5 EV能否终结纯电里程焦虑_科学黑匣子_2022年09月09日_微头条

    电车最大的痛点,“续航焦虑”能解吗?手机界大牛入场新能源汽车领域,一套组合拳,终结纯电车最后一道壁垒。AITO问界M5EV,高颜值,高智商,搭载鸿蒙3平台,纯电续航里程620里程,…

    2022年9月10日
  • 错过了苹果,错过了特斯拉,还会不会错过下一个潜力股

    当特斯拉、苹果或谷歌刚刚展露头角的时候,有多少人在最初看到了它们的价值?各行各业的风云变幻正是这样,由一个又一个颠覆者来推动。 交通分析公司Indix位于华盛顿州的柯克兰市,成立于…

    2022年6月14日
  • 推动消费与工业互联互通

    持续推动数字化助力消费品工业发展,一是提升多样化、多层次、快速迭代的供给能力;二是提升满足消费升级和改善消费体验的创新能力;三是提升企业聚集整合市场资源要素的竞争能力。 工信部等5…

    2022年8月3日
  • 苹果正式在韩国App Store中推出第三方支付,目前有四家提供商

    据报道,苹果公司今年早些时候曾宣布,将遵守韩国的一项新法律,在App Store应用商店中支持第三方支付提供商。从今日起,开发者终于可以在韩国App Store分发的应用程序中,申…

    2022年7月2日
  • 4人顶薪扛不住?勇士一招化解:格林+汤神换詹皇,詹库预定两连冠

    随着本赛季夺冠之后,勇士目前面临的压力不比争冠要更小,因为他们目前面临的奢侈税压力极大,同时格林、汤普森、维金斯、普尔都有资格进行续约,特别是维金斯、普尔的合同将会在下个赛季到期,…

    2022年7月29日
  • watch侦听器

    第一次传值,$watch()就能监听值的变化需要用到 immediate: true 参数; 父组件给子组件传递的是一个对象,改变其中的值,$watch()侦听不到,需要用到dee…

    2022年7月5日
  • 技术干货 -postman接口测试获取HTTP请求

    如果你正在使用API构建客户端应用程序—移动应用程序、网站或桌面应用程序—你可能希望看到在应用程序中发送和接收的实际HTTP请求流量。在某些情况下,可能会发现甚至没有文档记录的AP…

    2022年6月14日
  • 6月13日:曝光最新崩盘跑路和即将出事的问题平台

    1、派币:宣传到6月底上市兑现别墅豪车,一个派币价值千万的美梦,说派币在几个交易平台进行评估,通过后就可以在市面上自由流通了。不管怎么宣传,只要不交钱,就没有什么损失。当然虚拟币交…

    2022年6月14日

联系我们

联系邮箱:admin#wlmqw.com
工作时间:周一至周五,10:30-18:30,节假日休息