经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
策略模式+Spring配置类优化多if..else思路
来源:cnblogs  作者:CharltonW  时间:2023/7/28 10:21:41  对本文有异议

图示

image

1. 现状

场景: 假设设备上报不同类型的消息,我们要对不同类型的消息做不同的处理。如果我们通过if..else的方式处理的话会显得比较冗余。

例如:

  1. if("alarmEvent".equals(msg)){
  2. // 处理告警消息逻辑 ...
  3. }else if("deviceBase".equals(msg)){
  4. // 处理设备上报的基本信息 ...
  5. }else if("heartBeat".equals(msg)){
  6. // 处理设备心跳消息 ...
  7. }else {
  8. // ...
  9. }

2. 消息处理Handler

那么对于不同消息的不同的处理逻辑我们可以单独放在一个实现类中,这些类有着相同的行为,所以我们可以定义一个接口:

  1. public interface MessageHandler<T>{
  2. T invoke(String bizUpMessage); // 处理接收到的消息
  3. String getName();
  4. String getIdentification(); // 获取消息标志
  5. }

针对于不同的消息,我们可以有各自的实现

实现类1:

  1. @Component
  2. public class DeviceBaseInfoHandler implements MessageHandler<String> {
  3. @Override
  4. public String invoke(String bizUpMessage) {
  5. // 处理设备上报的基本信息 ...
  6. return "";
  7. }
  8. @Override
  9. public String getName() {
  10. return "";
  11. }
  12. @Override
  13. public String getIdentification() {
  14. return "DeviceBaseInfoRequest";
  15. }
  16. }

实现类2:

  1. @Component
  2. public class AlarmEventHandler implements MessageHandler<String>{
  3. @Override
  4. public String invoke(String bizUpMessage) {
  5. // 处理告警信息 ...
  6. return null;
  7. }
  8. @Override
  9. public String getName() {
  10. return "";
  11. }
  12. @Override
  13. public String getIdentification() {
  14. return "AlarmEventRequest";
  15. }
  16. }

3. Handler注册处

我们可以将上一步的消息处理对象,根据消息的标志(Identification)不同,将消息放在一个Map中:

  1. public class MessageHandlerRegisty {
  2. private Map<String, List<MessageHandler>> registerMap = new HashMap<>();
  3. // 注册各种 handler
  4. public void regist(String identification, MessageHandler handler){
  5. if(this.contains(identification)){
  6. get(identification).add(handler);
  7. } else {
  8. List<MessageHandler> list = new ArrayList<>();
  9. list.add(handler);
  10. registerMap.put(identification, list);
  11. }
  12. }
  13. public boolean contains(String identification){
  14. return registerMap.containsKey(identification);
  15. }
  16. public List<MessageHandler> get(String identification){
  17. return registerMap.get(identification);
  18. }
  19. }

4. 消息接收Service

消息接收接口

  1. public interface IMessageService {
  2. void messageReceived(String bizUpMessage); // 接收消息
  3. }

5. 消息接收ServiceImpl

消息接收实现类

  1. public class MessageServiceImpl implements IMessageService{
  2. public MessageHandlerRegisty registy;
  3. // 线程池
  4. public ExecutorService executorService = new ThreadPoolExecutor(3, 10, 15, TimeUnit.MINUTES, new LinkedBlockingQueue(1000), new LogdDiscardPolicy());
  5. public void messageReceived(String bizUpMessage){
  6. // 获取消息的标志Identification
  7. String identification = extractIdentification(bizUpMessage);
  8. if(StringUtils.isBlank(identification)){
  9. return;
  10. }
  11. if(!registy.contains(identification)){
  12. return;
  13. }
  14. for(MessageHandler handler : registy.get(identification)){
  15. execute(handler, bizUpMessage); // 多线程处理消息
  16. }
  17. }
  18. public MessageHandlerRegisty getRegisty() {
  19. return registy;
  20. }
  21. public void setRegisty(MessageHandlerRegisty registy) {
  22. this.registy = registy;
  23. }
  24. private void execute(MessageHandler handler, String bizUpMessage){
  25. executorService.submit(new IotMessageTask(handler, bizUpMessage));
  26. }
  27. public final class LogdDiscardPolicy extends ThreadPoolExecutor.DiscardPolicy {
  28. public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
  29. log.warn("MessageService pool is full !!!!!!!!");
  30. }
  31. }
  32. final class IotMessageTask implements Runnable {
  33. private MessageHandler handler;
  34. private String bizUpMessage;
  35. public IotMessageTask(MessageHandler handler, String bizUpMessage){
  36. this.handler = handler;
  37. this.bizUpMessage = bizUpMessage;
  38. }
  39. @Override
  40. public void run() {
  41. try {
  42. Stopwatch stopwatch = Stopwatch.createStarted();
  43. handler.invoke(bizUpMessage);
  44. stopwatch = stopwatch.stop();
  45. long cost = stopwatch.elapsed(TimeUnit.MICROSECONDS);
  46. logTime(cost);
  47. }catch (Exception e){
  48. log.error("handler execute error - ", e);
  49. }
  50. }
  51. private void logTime(long cost){
  52. if(cost > 50){
  53. log.warn(" handler -> {}, cost too much -> {}", handler.getName(), cost);
  54. } else {
  55. log.info("handler -> {}, cost -> {}", handler.getName(), cost);
  56. }
  57. }
  58. }
  59. }

6. 将MessageServiceImpl对象配置到spring容器

  1. @Configuration
  2. public class ManagerConfig {
  3. @Bean
  4. public IMessageService messageService(){
  5. MessageServiceImpl messageService = new MessageServiceImpl();
  6. messageService.setRegisty(buildRegisty());
  7. return messageService;
  8. }
  9. // 消息处理handler
  10. @Autowired
  11. private DeviceBaseInfoHandler deviceBaseInfoHandler;
  12. @Autowired
  13. private AlarmEventHandler alarmEventHandler;
  14. private MessageHandlerRegisty buildRegisty(){
  15. MessageHandlerRegisty registy = new MessageHandlerRegisty();
  16. registy.regist(deviceBaseInfoHandler.getIdentification(), deviceBaseInfoHandler);
  17. registy.regist(alarmEventHandler.getIdentification(),alarmEventHandler);
  18. return registy;
  19. }
  20. }

原文链接:https://www.cnblogs.com/charlton/p/17586887.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号