如何使用工厂+策略模式 优化多线程中的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(); } }

 

posted on 2021-01-26 14:56  好名字被谁用了  阅读(306)  评论(0编辑  收藏  举报

导航