单例模式的实践——跨接口存储、获取消息

本文探讨了在Java后端处理多个接口调用中产生的多条消息问题,通过避免过度耦合和保持接口纯净性,介绍了一种使用单例模式和Map进行消息暂存的解决方案。重点在于简化接口参数并实现消息的高效传递给Controller层。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        假设现在有一个需求:一个前端请求抵达Java后端后,经过6次接口调用,横跨3个类,在6个接口中,在调用第4个接口时,可能会产生多条消息,这些消息最终需要返回给前端。那么,如何将消息返回给Controller层的接口?最简单的方式可能是将在全部6个接口中封装一个对象,作为参数层层传递。但弊端也有2点:

  1. 使得接口之间耦合太深,为了实现这一个小小的需求,给6个接口都加上一个消息入参,一旦需求有变,需要修改这6个接口;
  2. 使得接口职责不再纯粹,接口应该是根据实际的需求,完成某项职责,如将文件存储到本地。

在不考虑引入外部工具,仅依靠Java自身的特性,使用单例模式,代码如下:

package com.**.**.**;

import java.util.HashMap;

/**
 * @author mason
 * @version 1.0
 * @description: 文件上传返回消息处理类
 * @date 2022/6/21 13:36
 */
public class FileHandleMsg {

    // 单例的文件处理类实例
    private static final FileHandleMsg fileHandleMsg = new FileHandleMsg();

    // 存储文件处理消息的MAP
    private HashMap<Long, String> msgMap = new HashMap<>();

    /***
     * @description 构造方法私有,禁止外部创建新实例
     * @return
     * @author mason
     * @date 2022/6/21 14:33
     */
    private FileHandleMsg(){}

    /***
     * @description 对外暴露的获取类实例的方法
     * @return com.sw.collect.vos.FileHandleMsg
     * @author mason
     * @date 2022/6/21 14:34
     */
    public static FileHandleMsg getInstance() {
        return fileHandleMsg;
    }

    /***
     * @description 添加文件处理返回消息
     * 以任务id作为key,若之前已存在该任务的消息,则将新消息追加到原有消息后面
     * @param taskId 任务id
     * @param msg 消息
     * @return void
     * @author mason
     * @date 2022/6/21 14:34
     */
    public void addMsg(Long taskId, String msg) {
         if (msgMap.containsKey(taskId)) {
             StringBuilder sb = new StringBuilder(msgMap.get(taskId));
             sb.append(msg);
             msgMap.replace(taskId, sb.toString());
         } else {
             msgMap.put(taskId, msg);
         }
    }

    /***
     * @description 获取文件处理消息,获取到消息后,从map中移除此消息
     * @param taskId 任务id
     * @param defaultMsg 默认消息,若该任务没有异常消息,则返回此默认消息
     * @return java.lang.String
     * @author mason
     * @date 2022/6/21 14:36
     */
    public String getMsg (Long taskId, String defaultMsg) {
        String msg = defaultMsg;
        if (msgMap.containsKey(taskId)) {
            msg = msgMap.get(taskId);
            msgMap.remove(taskId);
        }
        return msg;
    }

}

在保存消息的地方,按如下方式调用:

// 以taskId作为key存储在FileHandleMsg的Map中
FileHandleMsg.getInstance().addMsg(taskId, "文件存储异常");

 在Controller层,按如下方式调用。理论上Map存储的数据大小只受限于int的最大值,但如果不及时清理Map中的数据,还是会造成Map过大的情况,因此设定了在取得消息之后,随机从Map中删除该条记录。

return FileHandleMsg.getInstance().getMsg(taskId, "采集任务创建成功");

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值