zoukankan      html  css  js  c++  java
  • 策略模式优化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.

  • 相关阅读:
    在WCF中使用Flag Enumerations
    WCF开发教程资源收集
    [转]WCF 4 安全性和 WIF 简介
    Asp.Net Web API 2 官网菜鸟学习系列导航[持续更新中]
    Asp.Net Web API 2第十八课——Working with Entity Relations in OData
    Asp.Net Web API 2第十七课——Creating an OData Endpoint in ASP.NET Web API 2(OData终结点)
    Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)
    Asp.Net Web API 2第十五课——Model Validation(模型验证)
    函数 生成器 生成器表达式
    函数的进阶
  • 原文地址:https://www.cnblogs.com/yangyongjie/p/11409969.html
Copyright © 2011-2022 走看看