SpringBoot策略模式的实践使用

前言

在实际业务代码中,我们经常会碰到这样的代码:

String type = actualService.getRealtype(uid);
if(type.equals("typeA")){
    // do func A
}else if(type.equals("typeB")){
    // do func B
}else if(type.equals("typeC")){
    // do func C
}else[
   //...
}

这种 if-else 或者 switch-case 代码在每个分支都会判断分支类型,然后执行不同的方法获取结果,当代码分支比较少并且确定不会增加时,使用这种方式也是完全 ok 的,但是当分支比较多,并且后面可能会增加分支判断条件时,这种方式就违反了单一职责和开闭原则,因此对于我们开发工作中遇到这种情况,首先想到的是应该去优化这种代码中的“坏味道”,其中的方法之一就是考虑能不能用策略模式去重写,将代码和业务逻辑解耦,这样才有利于后续的维护工作。

策略模式,简单来说就是通过实现接口来重写不同的方法,从而通过上下文自动获取选择的策略方法并执行。

实践使用

以下基于 SpringBoot 的依赖注入实现策略模式。假设场景如下:某个客户需要订购多个资源,每个资源在不同资源池中,不同资源池下的资源也都不一样,在此处把原始的 if-else 代码逻辑优化为策略模式。

首先我们实现一个 ResourceStrategy 接口,并定义选择资源的抽象方法:

public interface ResourceStrategy {
    String orderInformation(String id);
}

然后根据 if-else 中的判断条件,构造三个资源类实现 ResourceStrategy 接口:

@Component("A")
public class ResourceA implements ResourceStrategy {
   @override
   public String orderInformation(String id){
      System.out.println("策略选择:Strategy A");
      return "A";
   }
}
@Component("B")
public class ResourceB implements ResourceStrategy {
   @override
   public String orderInformation(String id){
      System.out.println("策略选择:Strategy B");
      return "B";
   }
}
@Component("C")
public class ResourceC implements ResourceStrategy {
   @override
   public String orderInformation(String id){
      System.out.println("策略选择:Strategy C");
      return "C";
   }
}

注意其中每个类都需要标注策略类别名称。

然后我们需要写一个 SimpleContext 类来存储我们的策略类别,这时候就用到了 Spring 的依赖注入和自动发现。

@Service
public class SimpleContextService {
    @Autowired
    private final Map<String, Strategy> strategyMap = new ConcurrentHashMap<>();

    public SimpleContext(Map<String, ResourceStrategy > strategyMap) {
        this.strategyMap.clear();
        strategyMap.forEach(strategyMap::put);
    }

    public String getResource(String poolId){
        return strategyMap.get(poolId).orderInformation(poolId);
    }
}

接下来就是我们的实际调用场景了~,如下:

@RestController
@RequestMapping("/test")
public class TestController {
    @Autowired
    private SimpleContextService contextService;

    @GetMapping("/choose")
    public String choose(@RequestParam String poolId){
        return simpleContext.getResource(poolId);
    }

}

那么当我们的入参 poolId 传入 “A” 时,返回的结果如下:

策略选择:Strategy A
A

同理,不同传参都会进入不同的策略执行方法。过这个简单的 demo,就可以看到通过获取输入不同的资源池 id,可以自动的拿到不同的资源。
通过实践总结下来,使用策略模式的好处就是通过一个封装的上下文可以自由的切换不同的算法,省去多重判断,同时可以具有很好的扩展性。

总结

从上面可以看出,策略模式的优缺点十分明显,在我们实际的业务中,也需要看情况使用。

优点:

  • 策略模式符合开闭原则
  • 代码简洁,从上下文自动获取条件转移语句
  • 使用策略模式可以提高算法的保密性和安全性

缺点:

  • 每个策略都需要单独实现一个类,当策略很多时,会产生大量的策略类,会使代码出现“膨胀”
  • 客户端必须知道所有的策略
  • 策略模式的一系列算法地位是平等的,是可以相互替换的,事实上构成了一个扁平的算法结构,也就是在一个策略接口下,有多个平等的策略算法,就相当于兄弟算法。而且在运行时刻只有一个算法被使用,这就限制了算法使用的层级,使用的时候不能被嵌套使用

以上就是SpringBoot策略模式的实践使用的详细内容,更多关于SpringBoot策略模式的使用的资料请关注我们其它相关文章!

(0)

相关推荐

  • 详解SpringBoot结合策略模式实战套路

    1.1. 前言 我们都知道设计模式好,可以让我们的代码更具可读性,扩展性,易于维护,但大部分程序猿一开始都学过至少一遍设计模式吧,实战中不知用到了几成.接下来让我介绍一个结合SpringBoot的策略模式套路,让你的代码少些if-else 1.2. 开撸 废话不多说,直接告诉你今天的核心是@autowired,看到这个是不是很熟悉,你每天都在用,不就是自动注入Spring管理的Bean吗?但我们对它的用法很多时候就局限在全局变量的注入了,忘记了,它其实还可以构造器注入,类型注入或命名注入,那么结

  • SpringBoot策略模式的实践使用

    前言 在实际业务代码中,我们经常会碰到这样的代码: String type = actualService.getRealtype(uid); if(type.equals("typeA")){ // do func A }else if(type.equals("typeB")){ // do func B }else if(type.equals("typeC")){ // do func C }else[ //... } 这种 if-els

  • 浅谈用SpringBoot实现策略模式

    目录 问题的提出 策略模式代码的实现 进一步的思考 心得体会 问题的提出 阅读别人代码的时候最讨厌遇到的就是大段大段的if-else分支语句,一般来说读到下面的时候就忘了上面在判断什么了.很多资料上都会讲到使用策略模式来改进这种代码逻辑. 策略模式的类图如下: 只需要按照这个图写代码就可以了. 策略模式代码的实现 借助Spring框架我们能够轻松的实现策略模式. 举一个简单的例子,我们去咖啡店买咖啡的时候,会根据自己的喜好和胃容量选择大小杯.那么我们就要实现一个CoffeeStategy: pa

  • Springboot中实现策略模式+工厂模式的方法

    策略模式和工厂模式相信大家都比较熟悉,但是大家有没有在springboot中实现策略和工厂模式? 具体策略模式和工厂模式的UML我就不给出来了,使用这个这两个模式主要是防止程序中出现大量的IF ELSE IF ELSE.....接下来咱们直接实现,项目结构图: 工厂类FactoryStrategy负责创建策略的工厂,代码比较简单,比较关键的一点是AutoWired一个Map<String, Strategy> 这个会在初始化的时候将所有的Strategy自动加载到Map中,是不是很方便.使用c

  • 实践讲解SpringBoot自定义初始化Bean+HashMap优化策略模式

    策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 传统的策略模式一般是创建公共接口.定义公共方法-->然后创建实体类实现公共接口.根据各自的逻辑重写公共方法-->创建一个行为随着策略对象改变而改变的 context 对象-->根据不同的传参,调用不同的接口实现类方法,达到只改变参数即可获得不同结果的目的. 但是也可以明显发现,这种策略模式的实现方式,代码量较大,而且还要自定义要传递的参数,可能会引入一定数量的if/else,有一定的优

  • 浅析.net策略模式

    对于策略模式的理解:当一个业务有多种需求时候,在某个时候需要使用不同的方式来计算结果.这时候不同的方式可以理解为不同的策略来解决同样的问题. 例如:商场收银系统计算价格,1:正常计算 2:商品打折计算,3:满300减100等方式.就可以按三种策略来处理需求. 简单的说:策略模式就是用来封装算法的,但在实践中,我们发现可以用他来封装几乎任何类型的规则,只要在分析过程中听到需要在不同的时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性. 复制代码 代码如下: using System

  • 深入理解JavaScript系列(33):设计模式之策略模式详解

    介绍 策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户. 正文 在理解策略模式之前,我们先来一个例子,一般情况下,如果我们要做数据合法性验证,很多时候都是按照swith语句来判断,但是这就带来几个问题,首先如果增加需求的话,我们还要再次修改这段代码以增加逻辑,而且在进行单元测试的时候也会越来越复杂,代码如下: 复制代码 代码如下: validator = {             validate: function (value, ty

  • springboot整合EHCache的实践方案

    EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider. ehcache提供了多种缓存策略,主要分为内存和磁盘两级,所以无需担心容量问题. spring-boot是一个快速的集成框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置. 用户登录之后,几乎之后展示任何页面都需要显示一下用户信息.可以在用户登录成功之后将用户信息进行缓存,之后直

  • 从表单校验看JavaScript策略模式的使用详解

    众所周知的是,表单确实在前端,唔,或者说在网页中占有不小的比重.事实上,几乎每一个中大型网站都会有"登录注册"以验证用户信息.防止一些不可名状的隐患... 那么表单的优劣就成了前端开发者急需解决的问题.其实我更愿意称为"代码的可读性"或"可复用性"以及"是否冗杂". 表单也有"优劣"?你在开玩笑嘛? 我想你可以认真看下下面的代码,它用到了一些"新知识": <form action=

  • JAVA设计模式中的策略模式你了解吗

    目录 策略模式 策略模式是什么 策略模式的使用场景 策略模式实践 总结 策略模式 世界上本没有模式; 一些程序老鸟在长时间的编程工作总结出高效的代码写法被后世推崇; 并整理出固定的写法规范,这个写法规范目前收录有23种 这些规范被称之为 --> 设计模式 策略模式是什么 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 策略模式的使用场景 Q: 我们知道策略模式最重要的就是封装变化点,那边对于变化点我们一般用什么处理呢?

随机推荐