方法的职责

简介: 【8月更文挑战第2天】这段代码示例展示了在一个Web控制器类中的方法处理短信上行通知的过程,注意到for循环中的`oneRecord`变量。通过重构,将`oneRecord`的定义和赋值逻辑后置,实现更清晰的代码结构和更明确的职责划分。

先看下面Web控制器类里的这个方法,请注意for循环里的 oneRecord 变量。

@RestController
public class SmsReplyMsgNotify {
 
    @Autowired
    private CreateSmsModel createSmsModel;
    @Autowired
    private SmsDeliverManager smsDeliverManager;
    @Autowired
    private SmsDeliverBizService smsDeliverBizService;
 
    /**
     * 处理短信上行通知
     * @param request
     */
    @RequestMapping("/deliverMsg/{supplierFlag}")
    public String processRequest(@PathVariable("supplierFlag") String supplierFlag, HttpServletRequest request) {
        log.info("接收到短信上行的通知。 短信供应商={}", supplierFlag);
 
        SmsSupplierEnum supplierEnum = SmsSupplierEnum.getByReplyNotifyPath(supplierFlag);
        if(supplierEnum == null){
            log.error("短信上行通知,没有找到对应的供应商");
            throw new ResponseStatusException(HttpStatus.NOT_FOUND);
        }
 
        String supplierName = supplierEnum.getName();
        log.info("短信上行通知,找到对应的供应商:{}", supplierName);
        ISmsSDK supplierApi = createSmsModel.findSupplierApi(supplierName);
        Result<List<SmsDeliver>> notifyResult = supplierApi.handleReplyNotify(request);
        if(notifyResult.isSuccess()){
            List<SmsDeliver> smsDelivers = notifyResult.getResult();
            Integer count = smsDeliverManager.insertBatch(smsDelivers);
            log.info("{}短信上行通知,新增回调记录,准备新增数量:{},实际新增数量:{}", supplierName, smsDelivers.size(), count);
 
            //通知业务系统
            for (SmsDeliver smsDeliver : smsDelivers) {
                String oneRecord;
                if(SmsSupplierEnum.MDSmsSDK == supplierEnum){
                    oneRecord = String.format("%s,%s,%s,%s,%s", smsDeliver.getExt(), smsDeliver.getSn(),
                            smsDeliver.getPhone(), smsDeliver.getContent(), DateUtil.formatDateTime(smsDeliver.getReceiveTime()));
                }else{
                    oneRecord = String.format("0,0,%s,%s,%s",
                            smsDeliver.getPhone(), smsDeliver.getContent(), DateUtil.formatDateTime(smsDeliver.getReceiveTime()));
                }
                smsDeliverBizService.notifyCaller(oneRecord, smsDeliver);
            }
        }
 
        log.info("{}短信上行通知处理完成", supplierName);
        return notifyResult.getMessage();
    }
 
}

for循环里的这个 oneRecord 字符串变量,基于`smsDeliver`对象的5个属性拼接而成,并作为参数传递给业务层的 SmsDeliverBizService#notifyCaller 方法。

下面贴出来 SmsDeliverBizService#notifyCaller 的代码。可以看到,在最后的else中,它又把 oneRecord 变量作为参数传递给了该类的另一个方法 notifyCallerOldMethod。

@Component
public class SmsDeliverBizService {
 
    @Autowired
    private SmsReportManager smsReportManager;
    @Autowired
    private SmsSetingManager smsSetingManager;
 
 
    public void notifyCaller(String oneRecord, SmsDeliver deliverModel) {
        String content = deliverModel.getContent();
        if (StringUtils.isEmpty(content)) {
            return;
        }
 
        if (content.length() == 5) {
            String uri = notifyCallerNewMethod(deliverModel);
            log.info("短信上行通知-短信审批新通知地址:{}", uri);
            if (StringUtils.isEmpty(uri)) {
                return;
            }
            HttpUtil.get(uri, 100000);
        } else if (content.length() == 11) {
 
            ...
 
        } else {
            String uri = notifyCallerOldMethod(oneRecord);
            log.info("短信上行通知-短信审批旧通知地址:{}", uri);
            HttpUtil.get(uri, 100000);
        }
    }
 
    private String notifyCallerOldMethod(String oneRecord) {
        String url = smsSetingManager.findValue(SetingOptionConstant.SaasCallbackUrl);
        return url.replace("{0}", oneRecord);
    }
 
    // class中的其他方法(略)
}


那么,问题来了, oneRecord 应该定义在 Web控制器类里吗?

答案是不应该。这种做法不够合理,因为这导致了代码职责不清晰,且增加了控制器层与业务层之间的耦合度。

那么,问题来了,oneRecord 应该定义在 哪里 呢? 重构后的代码是什么?






答案

将 oneRecord 变量的定义和赋值逻辑 后置到最末端的 SmsDeliverBizService#notifyCallerOldMethod 方法里,不再通过方法传递。

涉及的改动点包括

  • SmsDeliverBizService#notifyCaller 方法参数去掉 String oneRecord,简化为 notifyCaller(SmsDeliver deliverModel)。
  • Web控制器方法里的 oneRecord 变量的赋值逻辑,移动到 SmsDeliverBizService#notifyCallerOldMethod 里。

这样改动后,使得代码结构更加清晰、各层职责划分更为明确。

image.png



目录
相关文章
|
6月前
|
设计模式 Java
常用设计模式(工厂方法,抽象工厂,责任链,装饰器模式)
有关设计模式的其他常用模式请参考 单例模式的实现 常见的设计模式(模板与方法,观察者模式,策略模式)
60 2
|
3月前
|
项目管理
类与类之间的协作模式问题之中介者模式在项目管理中有什么作用
类与类之间的协作模式问题之中介者模式在项目管理中有什么作用
|
3月前
|
存储 缓存 Java
|
3月前
类与类之间的协作模式问题之桥接模式在软件开发中应用的问题如何解决
类与类之间的协作模式问题之桥接模式在软件开发中应用的问题如何解决
|
6月前
|
设计模式 关系型数据库 Java
顺畅的职责传递-用责任链模式优化决策流程
本文首先通过经典场景展示了不使用设计模式时的问题与痛点。接着,引入责任链模式,详细讲解了其定义、解决问题的方式、结构图及工作原理,并通过重构示例展示了该模式如何解决原有痛点。最后,对责任链模式的优势、缺点以及在实际应用中可能遇到的挑战和限制进行了总结。责任链模式通过解耦请求发送者和接收者,提供了灵活的请求处理机制,适用于多个处理者按顺序处理请求的场景。然而,该模式也可能导致请求得不到处理或性能下降等问题,需在实际应用中权衡利弊。
206 0
顺畅的职责传递-用责任链模式优化决策流程
|
6月前
|
设计模式 XML C++
C++组合模式探索:以统一接口管理复杂的层次结构
C++组合模式探索:以统一接口管理复杂的层次结构
100 1
|
6月前
|
设计模式 缓存 编译器
【C/C++ 设计模式应用】精细化职责与灵活性:C++中的发送接口和数据转换基类设计
【C/C++ 设计模式应用】精细化职责与灵活性:C++中的发送接口和数据转换基类设计
107 0
|
设计模式 前端开发 Java
职责驱动设计以及状态模式的变化
职责驱动设计以及状态模式的变化
职责驱动设计以及状态模式的变化
|
架构师 数据可视化 领域建模
为什么你应该关心领域模型?
领域模型是DDD的核心,更是业务的深入认知
1877 0
为什么你应该关心领域模型?