前言:

  当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的更多相关文章

  1. 用工厂模式和策略模式优化过多的if-else

    多个if-else代码: @RunWith(SpringRunner.class) @SpringBootTest public class EducationalBackgroundTest { p ...

  2. 代码重构:用工厂+策略模式优化过多的if else代码块

    最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来.鉴于原代码会涉及到公司的隐私,因此就不贴出来了.下面以更加通俗易懂的案例来解析. 假如写一个针对员工 ...

  3. 利用策略模式优化过多 if else 代码

    前言 不出意外,这应该是年前最后一次分享,本次来一点实际开发中会用到的小技巧. 比如平时大家是否都会写类似这样的代码: if(a){ //dosomething }else if(b){ //dosh ...

  4. 代码重构:用工厂+策略模式优化冗余的if else代码块

    最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来.鉴于原代码会涉及到公司的隐私,因此就不贴出来了.下面以更加通俗易懂的案例来解析. 假如写一个针对员工 ...

  5. Java策略模式以及来自lambda的优化

    前言    设计模式是软件工程中一些问题的统一解决方案的模型,它的出现是为了解决一些普遍存在的,却不能被语言特性直接解决的问题,随着软件工程的发展,设计模式也会不断的进行更新,本文介绍的是经典设计模式 ...

  6. 新来的"大神"用策略模式把if else给"优化"了,技术总监说:能不能想好了再改?

    本文来自作者投稿,原作者:上帝爱吃苹果 目前在魔都,贝壳找房是我的雇主,平时关注一些 java 领域相关的技术,希望你们能在这篇文章中找到些有用的东西.个人水平有限,如果文章有错误还请指出,在留言区一 ...

  7. Java设计模式从精通到入门三 策略模式

    介绍 我尽量用最少的语言解释总结: Java23种设计模式之一,属于行为型模式.一个类的行为或者算法可以在运行时更改,策略对象改变context对象执行算法. 应用实例: ​ 以周瑜赔了夫人又折兵的例 ...

  8. JAVA设计模式之策略模式 - Strategy

    在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 ...

  9. java使用策略模式代替if/else

    平时在开发中避免不了使用大量的if else语句,但过多层的if else对于性能有很大的开销,类似如下代码 public class MainStart { public static void m ...

随机推荐

  1. iOS即时通讯之CocoaAsyncSocket源码解析二

    原文 前言 本文承接上文:iOS即时通讯之CocoaAsyncSocket源码解析一 上文我们提到了GCDAsyncSocket的初始化,以及最终connect之前的准备工作,包括一些错误检查:本机地 ...

  2. python监控ip攻击,服务器防火墙

    '''写一个程序,监控nginx的日志,如果有人攻击就加入黑名单 把ip加入黑名单的策略是,1分钟之内,如果同一个ip请求超过200次,那就加入黑名单''' '''分析:1.打开文件 2.循环读取 3 ...

  3. 阶段1 语言基础+高级_1-3-Java语言高级_09-基础加强_第1节 基础加强_4_Junit_@Before&@After

    为了演示输出一段话 测试add的方法 虽然报错了 但是打印的结果还是输出

  4. cookie/http/https

    今天再学习顺便外加复习下http的相关知识,顺便试试在笔记中导出一个长篇的图片回事怎么样的效果. HTTP相关知识,不是很全仅供参考

  5. 【ABAP系列】SAP ABAP ALV中设置CHECKBOX同时选中事件

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP ABAP ALV中设置CHE ...

  6. 神器 工具 推荐 SRDebugger

    unity asset store 关联下载 ,添加这个书签  javascript:var url = window.location.href;var id = url.substr(url.la ...

  7. Linux下杀进程

    $ ps -ef | grep firefox smx : ? :: /usr/lib/firefox-/firefox-bin smx : pts/ :: grep --color=auto fir ...

  8. es6基本介绍及使用

    1.什么是es6 ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了.它的目标,是使得JavaScript语言可以用来编写复杂的大型应 ...

  9. SpringBoot中设置自定义拦截器

    SpringBoot中设置自动以拦截器需要写一个类继承HandlerInterceptorAdapter并重写preHandle方法 例子 public class AuthorityIntercep ...

  10. SSH简单概念

    Spring:轻量级控制反转(IoC)和面向切面(AOP)的容器框架,让对象与对象之间的关系通过配置文件来管理,减低耦合度 IoC:凡是在容器中配置过的对象才会有Spring提供的服务和功能 AOP: ...