吐槽
要先吐槽!先得吃瓜!
请移步稍微阅读一哈上一篇关于极简策略模式的文章,深入笔者的心路历程,一起思考,一起学习,一起嗨皮!戳-->极简策略模式1.0...咳咳,我们严肃点,毕竟是程序员!要木讷刻板,笔者写完文章后,也颇为自得,发给了同学、朋友、某神奇的群,然后友好的程序员朋友们,就欢快的吐槽了起来,气氛一下子就起来了,他们主要指出(攻击)了以下的问题:
- 钩子与处理逻辑使用
Pair
结合太过麻烦(笔者觉得他们是在挑刺) - 使用
List
来存放策略是可以的,但是不觉得泛型
写得有点多么(又不是你手写,你怕啥?) - 策略初始化以及使用非常不明显,
层次
不清晰,冗余
复杂(笔者也觉得,我内心只承认这一点)
求索
听完大家友好的反馈以后,我很泄气,决定放弃,全文完...
别急,笔者在某种机缘巧合之下看到了一些关于枚举
的文章,发现枚举很妙,有了一些大胆的想法
- 枚举在加载时已经
初始化
,能有效的将使用和初始化分离 - 枚举结合的策略方法可以
隐藏
策略实现的细节,封装相关逻辑 - 枚举的增加和修改是非常清晰的,枚举的名称可以
有效的指出
当前策略的逻辑
码一码(故事纯属虚构,如有雷同,你肯定抄我的)
年关将近,大家关心的当然是
怎么给爽子洗白,哦不是,是川普离职了下家去哪里,不!!!!最关心的是打工人 能不能回家过年,笔者也是个打工人,灵机一动,给村里提供了一套先进的系统,过滤打工人的回乡请求,具体的逻辑实现如下面所示
1.村里直接拦路了,打工人直接原路返回
每一次拦路处理的逻辑抽象应该是这样的
public interface ConsumerStrategy<P, C> {
/**
* 暴露当前策略的钩子
*
* @return 判断钩子
*/
Predicate<P> predicate();
/**
* 暴露当前策略的消费逻辑
*
* @return 消费逻辑
*/
Consumer<C> consumer();
/**
* 真实的消费数据
*
* @param p 钩子来源
* @param c 消费来源
*/
default void handle(P p, C c) {
if (this.predicate().test(p)) {
this.consumer().accept(c);
}
}
}
系统维护了一套拦路询问逻辑,具体逻辑如下
/**
* 简化处理
* String 代表来自区域风险系数
* Integer 打工人
*/
enum ReturnHomeStrategy implements ConsumerStrategy<String, Integer> {
/**
* 高风险
*/
HIGH_RISK(from -> "HIGH_RISK".equals(from), i -> {
throw new RuntimeException("滚!");
}),
/**
* 中风险
*/
MIDDLE_RISK(from -> "MIDDLE_RISK".equals(from), i -> {
throw new RuntimeException("滚!");
}),
/**
* 低风险
*/
LOW_RISK(from -> "LOW_RISK".equals(from), i -> {
//todo 如果可以,也请滚
//todo 核算检测
//todo 居家隔离
});
private final Predicate<String> predicate;
private final Consumer<Integer> consumer;
ReturnHomeStrategy(Predicate<String> predicate, Consumer<Integer> consumer) {
this.predicate = predicate;
this.consumer = consumer;
}
@Override
public Predicate<String> predicate() {
return this.predicate;
}
@Override
public Consumer<Integer> consumer() {
return this.consumer;
}
}
系统运行情况如下
/**
* 某人回家
*
* @param from 代表来自区域风险系数
* @param id 打工人
*/
public void returnHome(String from, Integer id) {
for (ReturnHomeStrategy value : ReturnHomeStrategy.values()) {
value.handle(from, id);
}
}
系统运行了一段时间以后,广受好评,成功的保护了笔者村庄的安全,只是村长觉得,不够人性化,没有人文主义关怀,问笔者有没有好的方法,笔者肚子一晃,坏水一抖,说要不给他们开一个证明吧,有理有据的那种,体现村里的关爱,村长深深的看了笔者一眼,微微点了下头
2.村里直接拦路了,但是给开了书面证明,系统2.0上线了
改版以后,每一次拦路处理的逻辑抽象应该是这样的
public interface FunctionStrategy<P, T, R> {
/**
* 暴露当前策略的钩子
*
* @return 判断钩子
*/
Predicate<P> predicate();
/**
* 暴露当前策略的生产逻辑
*
* @return 消费逻辑
*/
Function<T, R> function();
}
系统维护新的拦路并签发书面证明的逻辑
/**
* 简化处理
* String 代表来自区域风险系数
* Integer 打工人
* String 村里开具证明
*/
enum ReturnHomeStrategy implements FunctionStrategy<String, Integer, String> {
/**
* 高风险
*/
HIGH_RISK(from -> "HIGH_RISK".equals(from), i -> "滚!"),
/**
* 中风险
*/
MIDDLE_RISK(from -> "MIDDLE_RISK".equals(from), i -> "滚!"),
/**
* 低风险
*/
LOW_RISK(from -> "LOW_RISK".equals(from), i -> "村里的祸害回来了,给他做个核算检测!");
private final Predicate<String> predicate;
private final Function<Integer, String> function;
public Predicate<String> getPredicate() {
return predicate;
}
public Function<Integer, String> getFunction() {
return function;
}
ReturnHomeStrategy(Predicate<String> predicate, Function<Integer, String> function) {
this.predicate = predicate;
this.function = function;
}
@Override
public Predicate<String> predicate() {
return this.predicate;
}
@Override
public Function<Integer, String> function() {
return this.function;
}
}
系统再次运行情况如下
/**
* 某人回家
*
* @param from 代表来自区域风险系数
* @param id 打工人
* @return 要证明
*/
public String returnHome(String from, Integer id) {
for (ReturnHomeStrategy value : ReturnHomeStrategy.values()) {
if (value.predicate().test(from)) {
return value.function().apply(id);
}
}
throw new RuntimeException("外星人,抓起来放进动物园卖门票!");
}
系统终于完美的上线了,世界真美好,空气真清新,就是村里笔者爱的小花也被拦在了村外,真是让人惆怅
正经总结
愚者千虑,必有一得笔者一直在思考各种设计模式的简化版的写法,比如原来也写过管道模式
的简化版(别去看,思考欠佳,怕丢人),本篇文章也是多次思考修改所得,也是希望大家能够获得一些灵感,让设计模式不再是重构甚至重开项目时的选择,让策略简单化,成为我们能用,易用,随心用的代码模板,增加编码效率,拥抱健康生活,祝好,谢谢!