• 策略模式优化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.

  • 相关阅读:
    【Vijos-P1285】佳佳的魔法药水-Dijkstra思想
    【NOIP2009提高组T3】最优贸易-双向SPFA
    【NOIP2009提高组T3】最优贸易-双向SPFA
    【Vijos-P1046】观光旅游-Floyd求最小环
    【Vijos-P1046】观光旅游-Floyd求最小环
    【Vijos-P1060】盒子-DP+组合数学
    mysql 结合keepalived测试
    set global read_only=0; 关闭只读,可以读写 set global read_only=1; 开始只读模式
    set global read_only=0; 关闭只读,可以读写 set global read_only=1; 开始只读模式
    -F, --flush-logs
  • 原文地址:https://www.cnblogs.com/yangyongjie/p/11409969.html
Copyright © 2020-2023  润新知