zoukankan      html  css  js  c++  java
  • 如何使用工厂+策略模式 优化多线程中的if else

    1.由于项目中if - else  太多 逻辑比较复杂 所以为了优化代码 使用 工厂 + 策略模式 进行处理

    参考地址 : https://m.toutiaocdn.com/i6772059095642931724/?app=news_article_lite&timestamp=1611325592&use_new_style=1&req_id=202101222226320100130260401A0FDF3D&group_id=6772059095642931724&share_token=0dec00e3-2862-488c-b437-2f83ea23f56b

    2. 使用场景 : 列入 登录 (微信  + QQ + 支付宝 + 手机号 +验证码 + web + APP + ...) 

    3.我遇到的场景比较特殊 (多线程 + 工厂 + 策略模式)

    直接上代码 

    优化前:

    优化后 :

    现在来看具体实现步骤:

    参考资料 : https://www.cnblogs.com/liberty777/p/13723981.html

     步骤一  首先准备一个需要实现的  Strategy 

    public interface Strategy {
        void compute(String type);
        /** 
        * 返回type
         * @param 
         * @return 
         */
        String getType();
    }
    

      步骤二 :建立工厂

    这里有个问题就是容易 找不到指定的类

    第二个参考资料提供了能解决的思路

    我这儿直接交给spring管理  @Component

    package com.shs.cts.message.executor;
    
    import com.shs.cts.message.mapper.CreditsMapper;
    import com.shs.cts.message.mapper.MessageMapper;
    import com.shs.cts.message.mapper.SysLogsMapper;
    import com.shs.cts.util.jgpush.JPushUtils;
    import org.springframework.stereotype.Component;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;
    
    
    @Component
    public class StrategyFactory {
    
        private Map<String, Strategy> map;
    
        private StrategyFactory(SysLogsMapper sysLogsMapper , MessageMapper messageMapper , JPushUtils jPushUtils , CreditsMapper creditsMapper){
            List<Strategy> strategies = new ArrayList<>();
            strategies.add(new MessageThread(messageMapper, jPushUtils));
            strategies.add(new LogThread(sysLogsMapper));
            strategies.add(new CreditsThread(creditsMapper));
            //这里是重点
            map = strategies.stream().collect(Collectors.toMap(Strategy::getType, strategy -> strategy));
            //等同于
    //        HashMap<String, Strategy> map = new HashMap<>();
    //        for (Strategy strategy : strategies) {
    //            map.put(strategy.getType(),strategy);
    //        }
        }
    
        public Strategy get(String type){
            return map.get(type);
        }
    
    
    }

    第三步 以日志线程为列

    package com.shs.cts.message.executor;
    
    import com.alibaba.fastjson.JSONArray;
    import com.shs.cts.message.mapper.SysLogsMapper;
    import com.shs.cts.util.constant.ConstantUtil;
    import com.shs.cts.util.domain.po.SystemLog;
    
    /**
     * describe: 日志线程类
     *
     * @author liuyanjun
     * @date 2020/12/29
     */
    public class LogThread implements  Runnable ,Strategy {
    
        private String value;
    
        private SysLogsMapper sysLogsMapper;
    
    //这里是优化之前调用传递使用的    
        public LogThread(String value, SysLogsMapper sysLogsMapper){
            this.value = value;
            this.sysLogsMapper = sysLogsMapper;
        }
    // 这里是在工厂里加载时使用的
        public LogThread(SysLogsMapper sysLogsMapper){
            this.sysLogsMapper = sysLogsMapper;
        }
    //日志处理逻辑
        @Override
        public void run() {
            System.out.println("日志获取到的值为:" + value);
            //执行推送和存储数据库
            SystemLog systemLog = JSONArray.parseObject(value, SystemLog.class);
            sysLogsMapper.save(systemLog);
    //        System.out.println("id -->" + save);
        }
    //实现Strategy  方法
        @Override
        public void compute(String value) {
            this.value = value;
        }
    //实现Strategy  方法
    //设置默认返回值 用于区分 跳转哪儿  
    @Override

    public String getType() {
    return ConstantUtil.ONE;
    }
    }

    第四步 优化代码

    package com.shs.cts.message.msg;
    
    import com.shs.cts.message.executor.ExecutorThread;
    import com.shs.cts.message.executor.Strategy;
    import com.shs.cts.message.executor.StrategyFactory;
    import com.shs.cts.util.constant.ConstantUtil;
    import com.shs.cts.util.redis.CustomCacheClient;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.ApplicationArguments;
    import org.springframework.boot.ApplicationRunner;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    
    /**
     * describe: redis 消息队列的demo使用
     *
     * @author liuyanjun
     * @date 2020/12/25
     */
    @Component
    public class RedisMQDemo implements ApplicationRunner {
      
        @Autowired
        private CustomCacheClient redisClient;
    //引入工厂
        @Resource
        StrategyFactory strategyFactory;
    
        public void operation(){
            while (true){
    //redis没有值 线程阻塞 String value
    = redisClient.getBLpLeftValue(ConstantUtil.RZ_MESSAGE);//取值 Strategy strategy = strategyFactory.get(value.substring(0,1));//找需要跳转到哪里 strategy.compute(value.substring(2));//赋值 ExecutorThread.threadPool.execute((Runnable)strategy);//启动线程 } } @Override public void run(ApplicationArguments args) throws Exception { operation(); } }
  • 相关阅读:
    【笔记】求数据前n个主成分以及对高维数据映射为低维数据
    使用sklearn中的fetch_mldata的错误情况以及可能可行的解决方法
    【笔记】求数据的对应主成分PCA(第一主成分)
    【笔记】主成分分析法PCA的原理及计算
    【笔记】如何确定梯度计算的准确性以及调试梯度下降法
    【笔记】随机梯度下降法
    【笔记】线性回归中的梯度下降法(实现以及向量化并进行数据归一化)
    AttributeError: module 'numpy' has no attribute 'num'
    灵雀云CTO陈恺:从“鸿沟理论”看云原生,哪些技术能够跨越鸿沟?
    容器云在证券行业的探索与实践
  • 原文地址:https://www.cnblogs.com/huanglp/p/14330336.html
Copyright © 2011-2022 走看看