## springboot 下策略模式的简单使用
1.灵魂三问
接手前人(已跑路)项目快乐否?
- 前人项目不写注释懵逼否?
一个方法中一堆if/else,且业务判断条件用简单数字(或英文字母),不带注释,想打人否?
所以,对于上述三个问题,我写了此随笔,然而————然并卵
这篇文章并不能让你不接手前人项目,并不能让你看懂没有注释的业务代码,也并不能让你以后不碰到if/else轰击波,但是——系尬系
鲁迅先生曾倡导过,如果你觉得政府腐败,那么你就应该努力考取公务员从政,去内部解决腐败;如果你觉得你的家乡建设不够美丽,那么你应该去建设他;如果你觉得人民素质不够高,那么你应该提高自身素质,以身作则;如果你觉得这功能完全是业务无理取闹,产品瞎接,那么你应该——好吧,业务爸爸一切都好。
瞎扯了半天,下面进入正题:
很多情况下,都没有一次到位得产品,也通常没有一次到位的业务需求,所以在后期的功能扩展中,很可能会造成不停的对原代码加入if/else分支判断,来满足新的业务需求,然而这对于后接手的程序员来说,在一堆if/else,几百行代码中去快速理解逻辑,并加入扩展,无疑是件很蛋疼的事(好吧,其实我的真实原因是:看起来有点丑),所以,如何改造自己的if/else代码,让其看的不显臃肿,直观简洁,我百度了一下,简单写了份在springboot环境下,利用策略模式改造代码的随笔,作为新知识的get体会!(好吧,策略模式其实很常见)
2.什么是策略模式
策略模式(Strategy Pattern):一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
运行时随时更改,有没有想到spring的自动注入?灵活,易扩展这也是其特点之一。有没有具体的实现步骤呢?有的!
3.简单实现步骤
简单的一个需求
首先,先假想一个简单的业务——新需求上,这个功能暂时有三个分支判断,三个分支对应不同的执行逻辑:
- 1——孙悟空逻辑
- 2——二师兄逻辑
- 3——唐僧逻辑
那么,首先,我们当然可以用if/else,switch,来做分支判断解决,好的解决,项目上线,后期扩展——
业务A有发话了,我觉得应该有4——沙师弟逻辑,对吧,是这样吧!好,我再加一个if,没问题的!
业务B突然有话发话了,我觉得应该有5——三只眼逻辑,对吧,不能没有二郎神啊!好,我再加一个if,
ojbk!- 业务C突然有想法了,咋不能忘了6——小白马吧,对吧,这么辛苦!嗯~~~,可以,应该可以快速实现!
业务D又来了,我觉得那白骨精挺漂亮的,是吧?你(漂亮你大爷)!!!!!!!好,还有没有漂亮的?
所以,这个分支的类,看起来有点难受!
策略模式实现步骤
好的话不多说,策略模式下,我们可以怎么解决这个问题呢?
- 首先,可以建立一个枚举类,用于存储分支判断的条件(也可以用静态变量)
public enum WestCommand {
W_SuWuKong(1,"孙爷爷","monkeyCommand"),
W_ZhuBaJie(2,"二师兄","pigCommand"),
W_TangSeng(3,"和尚","monkCommand");
private int value;
private String descreption;
private String beanName;
private WestCommand(int value,String descreption,String beanName){
this.value=value;
this.descreption=descreption;
this.beanName=beanName;
}
public int getValue(){
return value;
}
public String getDescreption(){
return descreption;
}
public String getBeanName(){
return beanName;
}
public static WestCommand getInstance(int value) {
for(WestCommand type : WestCommand.values()) {
if(type.getValue() == value) {
return type;
}
}
return null;
}
}
这个类用于存储分支判断条件,,,,,
- 建立策略角色接口
/**
* @说明:
* @类型名称:StrategyCommand
* @创建者: Raiden
* @创建时间: 2020/2/11 12:01
* @修改者: Raiden
* @修改时间: 2020/2/11 12:01
*/
public interface StrategyCommand {
String process();
}
- 创建具体策略角色
/**
* @说明:唐僧
* @类型名称:MonkeyCommand
* @创建者: Raiden
* @创建时间: 2020/2/11 12:02
* @修改者: Raiden
* @修改时间: 2020/2/11 12:02
*/
@Service
public class MonkCommand implements StrategyCommand {
@Override
public String process() {
return "和尚不曾调戏妖精了,施主还是别问了!!";
}
}
/**
* @说明:孙悟空
* @类型名称:MonkeyCommand
* @创建者: Raiden
* @创建时间: 2020/2/11 12:02
* @修改者: Raiden
* @修改时间: 2020/2/11 12:02
*/
@Service
public class MonkeyCommand implements StrategyCommand {
@Override
public String process() {
return "你孙爷爷叫你回家吃饭了!!";
}
}
/**
* @说明:二师兄
* @类型名称:MonkeyCommand
* @创建者: Raiden
* @创建时间: 2020/2/11 12:02
* @修改者: Raiden
* @修改时间: 2020/2/11 12:02
*/
@Service
public class PigCommand implements StrategyCommand {
@Override
public String process() {
return "你二师兄走位相当风骚!!";
}
}
- 创建上下文,获取具体角色
这里首先需要创建一个spring的工具类,用于根据id获取bean
/**
* @说明:
* @类型名称:StrategeContext
* @创建者: Raiden
* @创建时间: 2020/2/11 14:41
* @修改者: Raiden
* @修改时间: 2020/2/11 14:41
*/
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtils.context==null){
SpringUtils.context=applicationContext;
System.out.println("初始化容器成功------------");
}
}
//获取context
public static ApplicationContext getContext(){
return SpringUtils.context;
}
//通过名称获取bean
public static Object getBean(String beanName){
return getContext().getBean(beanName);
}
/**
* 通过类型获取bean
* @param tClass
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> tClass){
return getContext().getBean(tClass);
}
public static <T> T getBean(String beanName,Class<T> classType){
return getContext().getBean(beanName,classType);
}
}
然后,创建上下文
/**
* @说明:
* @类型名称:StrategyContext
* @创建者: Raiden
* @创建时间: 2020/2/11 15:05
* @修改者: Raiden
* @修改时间: 2020/2/11 15:05
*/
public class StrategyContext {
/**
* 获取对应的command实现类
* @param value
* @param classType
* @param <T>
* @return
*/
public static <T> T getStrategyBean(Integer value,Class<T> classType){
return SpringUtils.getBean(
WestCommand.getInstance(value).getBeanName(),classType);
}
}
在这里,一切准备工作基本算是完成了,下面,我们来看看效果
这里我是利用的springboot+springcloud创建了一个接口:
相应的控制层:
/**
* @说明:
* @类型名称:StrategyCrtl
* @创建者: Raiden
* @创建时间: 2020/2/11 11:58
* @修改者: Raiden
* @修改时间: 2020/2/11 11:58
*/
@RestController
@RequestMapping("/strategy")
public class StrategyCrtl {
@GetMapping("/{number}")
public ResponseEntity<String> getMessage(@PathVariable Integer number){
StrategyCommand bean = StrategyContext.getStrategyBean(number, StrategyCommand.class);
return ResponseEntity.ok(bean.process());
}
}
业务逻辑干掉了if/else,启动服务:
我们看一看看效果:1——孙悟空逻辑

2——二师兄逻辑

3——和尚逻辑

至于后来万一需要漂亮的白骨精,那么怎么做相信不用我多说,这看起来确实比if/else美观了不少,有人说差不多,那是因为业务爸爸层就只跟你说了一句话,万一有几百句呢?
## springboot 下策略模式的简单使用的更多相关文章
- C++设计模式 ==> 策略模式与简单工厂模式结合
简介 策略模式相较之于简单工厂模式适用于生产方法经常变化且方法较为繁多的情况,因为生产方法时常变化就会需要频繁修改工厂类,违背了开闭原则,这时就可以用策略选择类由客户端根据需求动态切换策略.且策略模式 ...
- SpringBoot结合策略模式实战套路
1. SpringBoot结合策略模式实战套路 1.1. 前言 我们都知道设计模式好,可以让我们的代码更具可读性,扩展性,易于维护,但大部分程序猿一开始都学过至少一遍设计模式吧,实战中不知用到了几成. ...
- springboot使用策略模式实现一个基本的促销
策略模式 定义了算法族,分别封装起来,让它们之间可以互相替换, 此模式让算法的变化独立于使用算法的客户 源码:https://github.com/youxiu326/sb_promotion.git ...
- 设计模式之策略模式&简单工厂模式
学习设计模式已经有非常长一段时间了,事实上先前已经敲过一遍了.可是老认为没有学到什么,认识也不够深刻.如今趁着重构机房,再又一次来过,也不晚. 事实上在敲了机房之后,看看模式,事实上,曾经非常难理解. ...
- Java实现策略模式的简单应用
在使用图像处理软件处理图片后,需要选择一种格式进行保存.然而各种格式在底层实现的算法并不相同,这刚好适合策略模式.编写程序,演示如何使用策略模式与简单工厂模式组合进行开发. 思路如下: 使用inter ...
- java笔记--策略模式和简单工厂模式
策略模式: --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3884781.html "谢谢-- 为什么使用:策略模式主要用于 ...
- SpringBoot使用策略模式+工厂模式
为了防止大量的if...else...或switch case代码的出现,可以使用策略模式+工厂模式进行优化. 在我的项目当中,报表繁多,所以尝试了这种方式进行优化报表的架构.代码很简单,如下: Fa ...
- 用SpringBoot实现策略模式
问题的提出 阅读别人代码的时候最讨厌遇到的就是大段大段的if-else分支语句,一般来说读到下面的时候就忘了上面在判断什么了.很多资料上都会讲到使用策略模式来改进这种代码逻辑. 策略模式的类图如下: ...
- php策略模式实现简单计算器
html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
随机推荐
- 【重要】Pro Git 第二版 简体中文
不管是入门还是精通git,下面这本书都是必读,同时它也是官方推荐书籍. Pro Git 第二版 简体中文 我自己还收集了一份网页版的progit,但可能不是progit第二版. 下载地址 ...
- floj 2265 【lxs Contest #141】航海舰队
首先抠出包围了阵形的最小矩形. 将地图拉伸成一条链,即将第一行.第二行.第三行按顺序连接.阵形也可以用同样的方法处理. 那么问题转化为,给定两个 01 串 S 和 T,问每个 S 中长度为 |T| 的 ...
- VS2015发布WEB项目
第一步:在打开的VS2015中,右击项目,在弹出的对话框中,点击“发布”. 第二步:配置发布的WEB项目. 1.为要发布的项目起个名称,一般和项目名称相同. 2.选择以文件系统发布. 3.设置相关配置 ...
- P1640 [SCOI2010]连续攻击游戏 二分图最大匹配 匈牙利算法
题目描述 lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备 ...
- Android Linker简介
简单介绍Android linker的基础知识,基于Android 10分支. linker的作用 考虑简单的HelloWorld程序. $ tree . . |-- jni | |-- Androi ...
- 大厂面试中三次握手延伸出来n连发你受得了?
目录 一.这是一次有故事的对话 二.三次握手的客户端服务端状态 1 先画个图看看有哪些状态 2 tcp协议内容解析 3 通过工具wireshark来验证我们所述 三.说下Linux网络编程常用API ...
- ORM执行原生SQL语句
# 1.connectionfrom django.db import connection, connections cursor = connection.cursor() # cursor = ...
- http的异步请求
需要用到的包(包版本应该可能不同): httpcore-4.1.4.jar httpsayncclient-4.0-alpha3.jar httpcore-nio-4.2-alpha3.jar /** ...
- [hdu2255] 奔小康赚大钱
Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有 \(n\) 间房间,刚好有 \(n\) 家 ...
- 通过Excel表创建sql脚本
Excel.sql脚本 1)准备好存有数据的excel表格: 这里我们有些小技巧可以让表下面和右边的表格隐藏,在第8行的位置按住“Ctrl+Shift+↓”可以选定下面的空格,然后鼠标右键 隐藏即可, ...