1.由于项目中if - else 太多 逻辑比较复杂 所以为了优化代码 使用 工厂 + 策略模式 进行处理
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(); } }