前言:

  当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. mongotemplate 简单使用

    怎么说呢,工作需要,不可能给你慢慢学的时间,一切以先解决当前jira为前提, mondb 安装不说了网上一搜就有,推荐图形管理界面 robo3t 比较直观 1.多条件查询这个比较简单 有两种方法 1C ...

  2. Java面试中hashCode()与equals(Object obj)方法关系的准确回答

    原文地址: https://blog.csdn.net/qq_19260029/article/details/77917925 hashCode()与equals(Object obj)都是Java ...

  3. 测开之路一百二十三:快速搭建python虚拟环境

    前提:已装好python3.4+且环境可正常运行 一:手动搭建: 准备好一个工作目录 管理员运行cmd,进入到准备的目录里面 执行命令:python -m venv 虚拟环境名 激活虚拟环境(在ven ...

  4. node+express 中安装nodemon实时更新server.js

    每次启动node server.js,有一个缺点,每次server.js文件有改动时,必须重新执行指令node server.js,新的代码才会起作用 解决方案1 全局安装 npm install s ...

  5. PCB布线设计-模拟和数字布线的异同(转)

    工程领域中的数字设计人员和数字电路板设计专家在不断增加,这反映了行业的发展趋势.尽管对数字设计的重视带来了电子产品的重大发展,但仍然存在,而且还会一直存在一部分与模拟或现实环境接口的电路设计.模拟和数 ...

  6. [Udemy] ES 7 and Elastic Stack - part 2

    Section 3: Searching with Elasticsearch query with json 分页返回 Sort full text 的内容不能用来sort, 比如movie的 ti ...

  7. Spring MVC配置文件

    都说开发Spring Web程序的配置文件很繁琐,所以就写了一篇配置博客, 首先是pom.xml文件 <project xmlns="http://maven.apache.org/P ...

  8. Spring MVC-学习笔记(5)spring MVC的文件上传、下载、拦截器

    1.文件上传.      spring MVC为文件上传提供了直接的支持,这种支持是即插即用的MultipartResolver(多部分解析器)实现的.spring MVC使用Apache Commo ...

  9. B.Petr and a Combination Lock

    https://codeforces.com/contest/1097/problem/A Petr and a Combination Lock time limit per test 1 seco ...

  10. struts2 中的 addActionError 、addFieldError、addActionMessage方法的区别添加错误信息

    转自:https://www.cnblogs.com/wangyp/archive/2011/07/13/2104828.html 一.addActionError("错误内容") ...