策略模式优化过多的IF ELSE
前言:
当if else的条件少的话,代码可阅读性及逻辑不影响阅读和扩展。一旦if else过多的话会导致逻辑比较混乱,不易扩展并且很容易出错。
实现方案:
1、定义一个@HandlerType注解,一个value属性,其值对应 if 条件的值
2、定义一个接口或者抽象类,抽AbstractHandler,抽象逻辑处理方法handler方法交给具体的业务实现
3、根据自己的业务,定义多个类实现AbstractHandler接口。每个实现类都注册到Spring容器中
4、对每个AbstractHandler的实现类都标注上@HandlerType注解,值为其要处理 if 条件的值
5、定义一个HandlerContext,用来扫描具有 @HandlerType注解的类,并将注解中的value作为key,对应的类作为value,初始化其属性handlerMap
6、通过条件从Spring容器中获取一个对应的AbstractHandler实例
7、执行实例对应的handler方法
举个例子:
有这样一个需求,需要监听一个Kafka topic下的不同类型的消息,类型从监听到的message中去区分,不同的类型的消息,处理逻辑也不同。代码:
1、定义自定义注解
/**
* Kafka监听消息的topic动作编号
*
* @author yangyongjie
* @date 2019/11/7
* @desc
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ListenerAction {
/**
* topic动作编号
*
* @return
*/
int value();
}
2、定义抽象处理器
/**
* 抽象的Kafka消息处理器
*
* @author yangyongjie
* @date 2019/11/7
* @desc
*/
public abstract class AbstractListenerHandler {
/**
* 消息处理
*
* @param data
*/
public abstract void handler(String data);
}
3、具体实现处理器,多个,这里只列一个
4、在具体的处理器上标注@HandlerType注解,表示其要处理的逻辑分支,这里表示只处理action为2001的消息
/**
* PartnerId 变更消息监听处理器
* @author yangyongjie
* @date 2019/11/7
* @desc
*/
@ListenerAction(2001)
@Component
public class PartnerIdListenerHandler extends AbstractListenerHandler { @Override
public void handler(String data) {
// dosomething
}
}
5、扫描具有 @HandlerType注解的类,并将注解中的value作为key,对应的类作为value,初始化其属性handlerMap
**
* 消息处理器的处理器
* 1.扫描包中标有@ListenerAction注解的类
* 2.将注解中的动作编号值作为key,对应的类作为value,初始化handlerMap
*
* @author yangyongjie
* @date 2019/11/7
* @desc
*/
@Component
public class ListenerHandlerContext implements ApplicationContextAware { private ApplicationContext applicationContext; /**
* 保存处理器的map,key为action,value为处理器Class
*/
private static final Map<Integer, Class> HANDLER_MAP = new HashMap<>(4); public AbstractListenerHandler getListenerHandlerInstance(Integer action) throws BssException {
Class<?> clazz = HANDLER_MAP.get(action);
if (clazz == null) {
throw new BssException(ResponseEnum.ERROR_HANDLER_NOT_FOUND.getCode(), ResponseEnum.ERROR_HANDLER_NOT_FOUND.getMsg());
}
return (AbstractListenerHandler) applicationContext.getBean(clazz);
} /**
* 扫描@ListenerAction,初始化ListenerHandlerContext,将其注册到Spring容器中
*
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
// 遍历所有带有@ListenerAction注解的类
Map<String, Object> listenerHandlerBeans = applicationContext.getBeansWithAnnotation(ListenerAction.class);
if (MapUtils.isNotEmpty(listenerHandlerBeans)) {
for (Object listenerHandlerBean : listenerHandlerBeans.values()) {
Integer action = listenerHandlerBean.getClass().getAnnotation(ListenerAction.class).value();
HANDLER_MAP.put(action, listenerHandlerBean.getClass());
}
}
}
}
6、获取处理器,执行逻辑分支
@Autowired
private ListenerHandlerContext listenerHandlerContext;
...
// 获取消息监听处理器
AbstractListenerHandler listenerHandler = listenerHandlerContext.getListenerHandlerInstance(action);
// kafka消息逻辑处理
listenerHandler.handler(data);
END.
策略模式优化过多的IF ELSE的更多相关文章
- 用工厂模式和策略模式优化过多的if-else
多个if-else代码: @RunWith(SpringRunner.class) @SpringBootTest public class EducationalBackgroundTest { p ...
- 代码重构:用工厂+策略模式优化过多的if else代码块
最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来.鉴于原代码会涉及到公司的隐私,因此就不贴出来了.下面以更加通俗易懂的案例来解析. 假如写一个针对员工 ...
- 利用策略模式优化过多 if else 代码
前言 不出意外,这应该是年前最后一次分享,本次来一点实际开发中会用到的小技巧. 比如平时大家是否都会写类似这样的代码: if(a){ //dosomething }else if(b){ //dosh ...
- 代码重构:用工厂+策略模式优化冗余的if else代码块
最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来.鉴于原代码会涉及到公司的隐私,因此就不贴出来了.下面以更加通俗易懂的案例来解析. 假如写一个针对员工 ...
- Java策略模式以及来自lambda的优化
前言 设计模式是软件工程中一些问题的统一解决方案的模型,它的出现是为了解决一些普遍存在的,却不能被语言特性直接解决的问题,随着软件工程的发展,设计模式也会不断的进行更新,本文介绍的是经典设计模式 ...
- 新来的"大神"用策略模式把if else给"优化"了,技术总监说:能不能想好了再改?
本文来自作者投稿,原作者:上帝爱吃苹果 目前在魔都,贝壳找房是我的雇主,平时关注一些 java 领域相关的技术,希望你们能在这篇文章中找到些有用的东西.个人水平有限,如果文章有错误还请指出,在留言区一 ...
- Java设计模式从精通到入门三 策略模式
介绍 我尽量用最少的语言解释总结: Java23种设计模式之一,属于行为型模式.一个类的行为或者算法可以在运行时更改,策略对象改变context对象执行算法. 应用实例: 以周瑜赔了夫人又折兵的例 ...
- JAVA设计模式之策略模式 - Strategy
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 ...
- java使用策略模式代替if/else
平时在开发中避免不了使用大量的if else语句,但过多层的if else对于性能有很大的开销,类似如下代码 public class MainStart { public static void m ...
随机推荐
- docker 提高效率 network-bridging 桥接
安装的时间顺序 bit3 192.168.107.128 wredis 192.168.107.129 wmysql 192.168.107.130 wslave 192.168.107.131 w ...
- 启动tomcat报错One or more listeners failed to start,却找不到任何错误日志的临时解决方案
在整合spring和quartz时,启动tomcat,服务台报以上错误,却找不到任何错误日志…… 参考了https://www.cnblogs.com/sxdcgaq8080/p/8005886.ht ...
- 《图解设计模式》读书笔记5-2 decorator模式
目录 代码演示 模式的角色和类图 思路拓展 Decorator模式即装饰器模式,就是对类进行装饰,下面通过代码说明. 代码演示 代码展示的内容 有一个类StringDisplay:表示一句话,比如he ...
- base64编解码的另外几个版本
#include "crypto/encode/base64.h" static const std::string base64_chars = "ABCDEFGHIJ ...
- SoapUI学习之SOAP和REST的区别
一.Soap和Rest的定义 SOAP(Simple Object Access Protocol 简单对象访问协议),用于在Web Service中把远程调用和返回封装成机器可读的格式化数据,事实上 ...
- javascript中json字符串对象转化
li = [1,2,3,4] s = JSON.stringify(li) ---转化为字符串 JSON.parse(s) --转化为对象
- java程序利用ansible修改redis服务参数
第一步,java调用shell paraname和paravalue是传给playbook的变量. try { String cmd5 = "sudo ansible-playbook /s ...
- js:获取单选组radio中的被选择的数据
现在有一name为sex的单选组,代表的是选择性别,要求获取radio中被选择的选项值 <div class="sexDiv"> 用户性别: <input cla ...
- 加密算法:DES、AES等
指标:运算速度.安全性.资源消耗 对称加密算法(加解密密钥相同): 非对称算法(加密密钥和解密密钥不同): 散列算法比较: 对称与非对称算法比较: 算法选择(从性能和安全性综合) 对称加密: AES( ...
- C# DataSet转JSON
经常会遇到系统数据交互采用JSON数据格式进行交互的,避免不必要的重复工作,记录下自己的处理方式. 获取数据集之后,通过函数对数据集信息进行整理通过.Net Framework3.5提出的JavaSc ...