一、前言

策略模式可能是在工作中使用最多的,也是在面试中最常提到的,代码重构和优化的必备!

小编之前也是一直说,其实没有真正的实战;最近有了机会实战了一下,来分享一下使用心得和在企业级的使用!

二、策略模式

1. 什么是策略模式

策略模式,英文全称是 Strategy Design Pattern。在 GoF 的《设计模式》一书中,它是这样定义的:

定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。策略模式可以使算法的变化独立于使用它们的客户端(这里的客户端代指使用算法的代码)。

2. 策略模式结构组成

  • Strategy:抽象策略类,一般为接口或者策略类
  • ConcreteStrategy:具体算法实现策略类
  • Context:环境或者上下文类,用于统一执行具体策略

其实以上三部分用白话文来解释就是:

需要一个接口和策略进行规范和约束接口和方法,这时需要一些具体的实现算法类去继承或者实现刚刚的接口和策略,最后通过一个环境或者上下文,也可以叫做工厂根据类型进行调用具体的算法!

3. 使用场景

  • 避免冗长的 if-else 或 switch 分支判断
  • 需要动态地在几种算法中选择一种
  • 对客户隐藏具体策略 (算法) 的实现细节,彼此完全独立,扩展其余不受影响

具体场景一般为:

  • 支付方式选择
  • 打折、满减方式选择
  • 根据类型调用不同的系统

4. 优缺点

优点:

  • 扩展性好
  • 符合开闭原则
  • 符合单一职责原则
  • 可读性好
  • 便于维护
  • 避免多层判断

缺点:

  • 策略过多,导致策略类
  • 对新手读代码不友好

三、策略模式实战

1. 实战例子

今天小编根据春夏秋冬四季需要做不同的事情来演示一下策略模式的使用方案;

需求是:

如果是春天,就要去放风筝

如果是夏天,就要去游泳

如果是秋天,就要去看枫叶

如果是冬天,就要去打雪仗

没有使用策略模式的话,肯定就是

if-if else进行实现!

下面就带大家体会一下具体使用哈!!

2. 策略接口

/**
* 四季策略
* @author wangzhenjun
* @date 2022/12/1 9:30
*/
public interface SeasonsStrategy { /**
* 根据季节去执行不同的方案
* @param seasons
* @return
*/
String execute(String seasons);
}

3. 春季具体实现

/**
* 春季具体实现
* @author wangzhenjun
* @date 2022/12/1 9:34
*/
// 指定容器的名称,不指定默认为类名称首字母小写
@Component("spring")
public class SpringStrategy implements SeasonsStrategy{
@Override
public String execute(String seasons) { return seasons + "来了!我们一起去放风筝吧!";
}
}

4. 夏季具体实现

/**
* 夏季具体实现
* @author wangzhenjun
* @date 2022/12/1 9:34
*/
// 指定容器的名称,不指定默认为类名称首字母小写
@Component("summer")
public class SummerStrategy implements SeasonsStrategy{
@Override
public String execute(String seasons) { return seasons + "来了!我们一起去游泳吧!";
}
}

5. 秋季具体实现

/**
* 秋季具体实现
* @author wangzhenjun
* @date 2022/12/1 9:34
*/
// 指定容器的名称,不指定默认为类名称首字母小写
@Component("autumn")
public class AutumnStrategy implements SeasonsStrategy{
@Override
public String execute(String seasons) { return seasons + "来了!我们一起去放看枫叶吧!";
}
}

6. 冬季具体实现

/**
* 冬季具体实现
* @author wangzhenjun
* @date 2022/12/1 9:34
*/
// 指定容器的名称,不指定默认为类名称首字母小写
@Component("winter")
public class WinterStrategy implements SeasonsStrategy{
@Override
public String execute(String seasons) { return seasons + "来了!我们一起去打雪仗吧!";
}
}

7. 上下文工厂实现

private Map<String, SeasonsStrategy> seasonsMap;这是最重要的,很多时候我们都知道怎么进行策略和实现怎么写,不知道怎么统一去放进去,来进行调用,可以自己放在map中。当然spring已经给我们组装好了,只要按需调用即可!

核心:

Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id,value值则为对应的策略实现类!

/**
* 环境或者上下文类,用于统一执行具体策略
* @author wangzhenjun
* @date 2022/12/1 9:56
*/
@Component
public class SeasonsFactory {
/**
* Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id,value值则为对应的策略实现类
*/
@Autowired
private Map<String, SeasonsStrategy> seasonsMap; /**
* 处理四季统一入口方法
* @param seasons
* @param beanName
* @return
*/
public String handle(String seasons,String beanName){
// 根据bean的名称获取对应的算法处理类
SeasonsStrategy seasonsStrategy = seasonsMap.get(beanName);
String execute = seasonsStrategy.execute(seasons);
return execute;
}
}

8. controller处理

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController { @Autowired
private SeasonsFactory seasonsFactory; @GetMapping("/strategyTest/{seasons}/{beanName}")
public Result strategyTest(@PathVariable("seasons") String seasons,@PathVariable("beanName") String beanName){
String handle = seasonsFactory.handle(seasons, beanName);
return Result.success(handle);
}
}

9. 测试

http://localhost:8087/test/strategyTest/春天/spring



http://localhost:8087/test/strategyTest/夏天/summer

四、总结

在策略模式中定义了一系列算法,将每一个算法封装起来,并让它们可以相互替换,互不影响。

策略模式得益于按照开闭原则进行设计,各个具体算法按照单一职责原则设计; 提高了代码的复用性,对客户隐藏具体策略 (算法) 的实现细节,彼此完全独立,扩展其余不受影响;避免if-else 或 switch 分支语句判断;其缺点在于客户端必须知道所有的策略类,增加了系统中类的个数。

在日常开发一般用于消除多重判断,有时候不要为了用设计模式而用设计模式,一定要结合业务场景,过度设计也是很致命的!!

如果对你有帮助,还请不要吝啬您的发财小手,你的一键三连是我写作的动力,谢谢大家哈!!


可以看下小编的微信公众号,文章首发看,欢迎关注,一起交流哈!!

Springboot整合策略模式概念->使用场景->优缺点->企业级实战的更多相关文章

  1. springBoot整合spring security+JWT实现单点登录与权限管理--筑基中期

    写在前面 在前一篇文章当中,我们介绍了springBoot整合spring security单体应用版,在这篇文章当中,我将介绍springBoot整合spring secury+JWT实现单点登录与 ...

  2. 功能:SpringBoot整合rabbitmq,长篇幅超详细

    SpringBoot整合rabbitMq 一.介绍 消息队列(Message Queue)简称mq,本文将介绍SpringBoot整合rabbitmq的功能使用 队列是一种数据结构,就像排队一样,遵循 ...

  3. SpringBoot整合SpringSecurity示例实现前后分离权限注解

    SpringBoot 整合SpringSecurity示例实现前后分离权限注解+JWT登录认证 作者:Sans_ juejin.im/post/5da82f066fb9a04e2a73daec 一.说 ...

  4. SpringBoot整合MyBatisPlus配置动态数据源

    目录 SpringBoot整合MyBatisPlus配置动态数据源 SpringBoot整合MyBatisPlus配置动态数据源 推文:2018开源中国最受欢迎的中国软件MyBatis-Plus My ...

  5. SpringBoot整合Swagger和Actuator

    前言 本篇文章主要介绍的是SpringBoot整合Swagger(API文档生成框架)和SpringBoot整合Actuator(项目监控)使用教程. SpringBoot整合Swagger 说明:如 ...

  6. springboot整合websocket高级版

    目录 sockjs介绍 产生的原因 环境搭建 springboot整合sockjs 使用场景 聊天室开发 点对点通信 群聊 效果 总结 加入战队 微信公众号 上一章节我们说了websocket的优缺点 ...

  7. springboot整合Shiro功能案例

    Shiro 核心功能案例讲解 基于SpringBoot 有源码 从实战中学习Shiro的用法.本章使用SpringBoot快速搭建项目.整合SiteMesh框架布局页面.整合Shiro框架实现用身份认 ...

  8. SpringBoot整合Swagger2(Demo示例)

    写在前面 由于公司项目采用前后端分离,维护接口文档基本上是必不可少的工作.一个理想的状态是设计好后,接口文档发给前端和后端,大伙按照既定的规则各自开发,开发好了对接上了就可以上线了.当然这是一种非常理 ...

  9. 001 SringBoot基础知识及SpringBoot整合Mybatis

    1.原有Spring优缺点分析 (1)优点 Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE)的轻量级代替品.无需开发重量级的Enterprise J ...

  10. Redis-基本概念、java操作redis、springboot整合redis,分布式缓存,分布式session管理等

    NoSQL的引言 Redis数据库相关指令 Redis持久化相关机制 SpringBoot操作Redis Redis分布式缓存实现 Resis中主从复制架构和哨兵机制 Redis集群搭建 Redis实 ...

随机推荐

  1. CentOS6/7开机启动配置

    最近在配置Linux系统的ntp校时,涉及到开机启动问题,总结一下 两个环境: CentOS release 6.5 (Final) CentOS Linux release 7.9.2009 (Co ...

  2. Scanner的用法 从键盘输入

    先导入包 import java.util.Scanner; 后输入 Scanner Sc=new Scanner(System.in); //(Sc可以自定义,无实质意义) int i; i=Sc. ...

  3. 后端框架学习-----mybatis(4)

    文章目录 4.解决属性名和字段名不一致的问题 4.解决属性名和字段名不一致的问题 1.问题.数据库字段名和属性名不一致,导致查出的数据部分为空 2.resultMap(用于解决数据库表中的字段和属性) ...

  4. 【Odoo】Odoo16-性能优化提升

    上海序说科技,专注于基于Odoo项目实施,实现企业数智化,助力企业成长. 老韩头的开发日常,博客园分享(2022年前博文) 10月12日,Odoo16版本正式发布,本文将就Odoo官方在性能方面做的优 ...

  5. 知识图谱-生物信息学-医学论文(BMC Bioinformatics-2022)-挖掘阿尔茨海默病相关KG来确定潜在的相关语义三元组用于药物再利用

    论文标题: Mining On Alzheimer's Diseases Related Knowledge Graph to Identity Potential AD-related Semant ...

  6. C# String.IsNullOrEmpty()方法的使用

    IsNullOrEmpty(string)是String类的一个有参的方法,方法需要类的调用,所以String.IsNullOrEmpty(string) IsNullOrEmpty是判断字符串的Nu ...

  7. photoshop 2021 for mac安装教程,亲测可用!!!

    小编分享下photoshop cc 2021 for mac 安装教程,适配M1芯片,让大家完美使用ps2021,畅享所有新功能Adobe Photoshop2021(简称PS) 新版本主要增加了Ne ...

  8. 一、Go语言开篇介绍

    Go语言开篇介绍 Go语言 是Google公司 在2007开发一种静态强类型.编译型语言,并在 2009 年正式对外发布. Go语言以其近C的执行性能和近解析型语言的开发效率,以及近乎于完美的编译速度 ...

  9. 测试开发jmeter forEach控制器

    测试开发jmeter forEach控制器 forEach控制器的使用场景:主要是对大量数据轮询就行接口请求 forEach控制器的使用前提:将数据进行参数化 测试开发jmeter forEach控制 ...

  10. selenium 添加特殊配置(如不完整 希望各位大神评论告诉我)

    options 常用配置 #添加特殊配置 options=webdriver.ChromeOptions() #设置默认编码为utf-8,也就是中文 options.add_argument('lan ...