首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >使用策略模式 + 函数式接口优化 MQ 消息处理

使用策略模式 + 函数式接口优化 MQ 消息处理

原创
作者头像
Java king
修改2025-05-28 13:44:49
修改2025-05-28 13:44:49
2900
举报
文章被收录于专栏:后端Java后端Java

一、背景说明

在传统消息队列(MQ)消费处理场景中,我们通常采用大量 if-else 或 switch-case 结构来根据不同的消息类型执行不同的业务逻辑。

存在的问题:

  • if-else 嵌套层级深、代码不易维护
  • 新增类型需要修改原有逻辑,违反开闭原则
  • 业务逻辑与消息处理耦合度高

二、实现目标

  • ✅ 消除冗余的 if-else 分支结构
  • ✅ 解耦消息处理逻辑与调用方式
  • ✅ 利用 Java 8 函数式接口优雅传递处理方法
  • ✅ 实现更强的可维护性和扩展性

三、核心实现结构

1. 定义处理逻辑枚举(策略集合)

代码语言:java
复制
public enum EvaluationEnum {
    SURVEY_DATA_GENERATE("XXX", EvaluationUtil::surveyDataGenerate),
    PERSONNEL_DATA_GENERATE("XXX", EvaluationUtil::personnelDataGenerate);

    private final String desc;
    private final Consumer<EvaluationDto> setter;

    EvaluationEnum(String desc, Consumer<EvaluationDto> setter) {
        this.desc = desc;
        this.setter = setter;
    }

    public Consumer<EvaluationDto> getSetter() {
        return setter;
    }
}
  • 每个枚举值代表一种处理策略
  • 使用 Consumer<EvaluationDto> 函数式接口传入对应处理方法
  • 描述信息 desc 用于前端展示或日志用途

2. 消息监听者中调用策略

代码语言:java
复制
@Service("evaluationListener")
public class EvaluationListener implements ChannelAwareMessageListener {

    private static final Logger log = LogManager.getLogger(EvaluationListener.class);

    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        try {
            BasQueueTask basQueueTask = JSONObject.parseObject(new String(message.getBody()), BasQueueTask.class);
            EvaluationDto evaluationDto = JsonUtil.fromJsonToBean(basQueueTask.getMsgBody().toString(), EvaluationDto.class);
            EvaluationEnum.valueOf(basQueueTask.getScene()).getSetter().accept(evaluationDto);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            log.error("[EvaluationListener]消息发送异常,已入死信队列。消息内容:{},e:", JsonUtil.toJson(message), e);
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
        }
    }
}

3. 发送端设置场景值

代码语言:java
复制
BasQueueTask basQueueTask = new BasQueueTask();
basQueueTask.setMsgBody(evaluationDto);
basQueueTask.setScene(
    evaluationDto.getReportType().equals(ReportManageTypeEnum.SURVEY.getId()) 
    ? EvaluationEnum.SURVEY_DATA_GENERATE.name() 
    : EvaluationEnum.PERSONNEL_DATA_GENERATE.name()
);

rabbitTemplate.convertAndSend(
    MsgQueueEnum.RPT_EVALUATION.getExchangeName(),
    MsgQueueEnum.RPT_EVALUATION.getQueueName(),
    basQueueTask
);

四、函数式接口说明

常用接口

接口名

参数数量

返回值

用途

Consumer<T>

1

消费一个输入参数

BiConsumer<T,U>

2

消费两个输入参数(例如带条件处理)

示例:

代码语言:java
复制
Consumer<String> log = System.out::println;
log.accept("Hello World");

BiConsumer<String, Integer> printer = (label, value) -> 
    System.out.println(label + ": " + value);

printer.accept("数量", 10);

五、设计模式分析

🎯 使用的设计模式:

  1. 策略模式(Strategy Pattern)
    • 每种处理逻辑封装成一个策略,避免大量 if-else
    • 增加策略只需新增枚举,无需修改现有代码
  2. 中介者模式(Mediator Pattern)
    • 使用 MQ 做消息中介
    • 解耦 Producer 和 Consumer
  3. 函数式接口(Java 8)
    • 方法引用实现逻辑传递
    • 配合策略枚举提升灵活性

六、技术亮点总结

✅ 使用枚举组织策略,语义明确

✅ Java 8 函数式接口传递行为,代码更简洁

✅ 解耦发送者与处理者,符合设计原则

✅ 扩展简单,只需添加新的枚举值

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、背景说明
    • 存在的问题:
  • 二、实现目标
  • 三、核心实现结构
    • 1. 定义处理逻辑枚举(策略集合)
    • 2. 消息监听者中调用策略
    • 3. 发送端设置场景值
  • 四、函数式接口说明
    • 常用接口
    • 示例:
  • 五、设计模式分析
    • 🎯 使用的设计模式:
  • 六、技术亮点总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档