IF-ELSE
清除计划)0202年,代码帝国IF-ELSE
模块越加庞大,严重影响了帝国的运行,使得系统不堪重负,于是帝国推出了IF-ELSE
清除计划,顿时,一场腥风血雨席卷了整个帝国,无数势力你方唱吧我登场,阴谋阳谋你来我去精彩纷呈,此时,一个叫做魔法海螺的组织提出了自己的见解,随着这个组织的出现,历史的车轮开始滚动了起来,岁月翻开了新的篇章
咳咳,不扯了,不知道大家最近有没有在掘金刷到干掉IF-ELSE
的文章,各位大佬都针对各个场景提出了很好的方法,但是,作为一个CRUD-BOY
,我觉得策略模式其实适应场景是有限的,主要的原因有以下几点
每个IF-ELSE
都需要独立的处理策略,即单独实现类(就算是内部类开销也很大)
方法簇
(所有的策略方法)需要钩子方法钩中自己处理的逻辑,主要有这些方式
Map<String,Handler>
显性暴露钩子注解
便携式暴露钩子SpringBeanName
侵入式暴露钩子涉及到策略分层时,策略方法之间的相互嵌套回调
是灾难性的
输入输出固定
,增加一个参数都需要修改所有的方法簇废弃的策略以及新增的策略
混杂一起,不敢随便修改和删除重复代码
,虽然策略分层,但是实际业务会有大量重复的代码,抽了不够内聚
,不抽IDEA一片冒黄CRUD-BOY
我就是Diss策略模式(好的,这就是私货手动滑稽)CRUD
场景策略模式写不动,也觉得没必要我是不敢动的
,虽然后面改起来很爽管道模式
,是在简单场景清理IF-ELSE的绝佳手段,大家在学习管道时,会不会感觉跟责任链
很像,但是我觉得是有区别的,为了方便大家区分,梳理一下
管道模式由来已久,但是管道模式其实也很复杂,会有Pipeline管道
、Context上下文
、Status状态
、Valve阀门
等,("▔□▔)那我为啥要选管道模式,掀桌了,这跟策略模式比较来根本毫无优点,还是一样一大团东西,混在一起,作为CRUD-BOY
我根本用不着,稍安勿躁,我们先搞搞简单的管道,让我们更简单易用
管节逻辑
public interface Step<IN, OUT> { /** * 管节处理逻辑 * * @param input 管节输入 * @return OUT 管节输出 */ OUT process(IN input); } 复制代码
管道逻辑
public class Pipeline<IN, OUT> { /** * 当前管节 */ private Step<IN, OUT> current; /** * 此构造方法只用于初始化 * 头部管节 即第一个管节 * * @param current 当前管节 */ public Pipeline(Step<IN, OUT> current) { this.current = current; } /** * 拼接管节并返回新的管道 * 这里注意一下,返回的是完整的管道 * 即最顶部管节的输入,最底部管节的输出 * @param next 下一个管节 * @param <NEXT> 下一个管节的输出 * @return 拼接了下一个管节的管道 */ public <NEXT> Pipeline<IN, NEXT> pipe(Step<OUT, NEXT> next) { return new Pipeline<>(input -> next.process(current.process(input))); } /** * 真实执行 * @param input 输入 * @return 输出 */ public OUT execute(IN input) { return this.current.process(input); } } 复制代码
举个栗子
//头部管节 Pipeline<Integer, String> start = new Pipeline<>(input -> String.valueOf(input)); //继续增加管节 Pipeline<Integer, String> pipeline = start .pipe(input -> Integer.parseInt(input) + 1) .pipe(input -> Collections.singletonList(String.valueOf(input + 1))) .pipe(input -> input.get(0)); //真实执行 String execute = pipeline.execute(1); 复制代码
优点
这样的管道实现有没有让大家眼前一亮呢?没错,这就是非常简单的管道实现,没有实现类,没有上下文,没有开关,没有状态,只有简单的处理逻辑,所有的一切都是如此的简单,对我而言,就是我再写CRUD
时,IF-ELSE
少了,然后没有复杂的策略类需要管理,平常写写CRUD就很开心,不用再搞很多复杂的代码了
如果以上代码在IDEA中打开,你会发现提示你改成Lambda格式,哦???然后当你打开Java8
的function包下面的**Function<T, R>**接口时,这就是见证奇迹的时刻,bing~~~~
R apply(T t); 复制代码
花擦,这个好像一个管节,然后你会发现以下代码
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } 复制代码
("▔□▔),这不就是接管节的方法么,我果然是个CRUD-BOY
,人家早就实现了,你还在造轮子,关键造出来还没有别人秀,真的是没来由的一股忧伤,然后,让我们试试咋用呗
举一颗悲伤的栗子
//头部管节 Function<Integer, String> start = input -> String.valueOf(input); //继续增加管节 Function<Integer, String> pipeline = start .andThen(input -> Integer.parseInt(input) + 1) .andThen(input -> Collections.singletonList(String.valueOf(input + 1))) .andThen(input -> input.get(0)); //真实执行 String execute = pipeline.apply(1); 复制代码
咋样,看到这个代码是不是心怦怦跳,恨不得马上打开IDEA撸一波代码,感受酣畅淋漓的管道模式,也就是撸---管道模式,兄弟,不能污,要纯洁,纯洁的程序员才能写出碰触心灵的代码。。。不说了,请开心的写起来吧
如果,你没有被我带歪的话,其实我们说的是IF-ELSE
清除计划,但是直到现在都没有说怎么清理IF-ELSE
,所以其实这篇文章相当于清理计划的前传,我会在下一篇文章里面,讲述怎么通过Java8
新特性Optional结合Function实现清理IF-ELSE
的计划,欢迎下次光临,谢谢惠顾,祝端午安康,阖家幸福!