方法的职责

简介: 【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



目录
相关文章
|
3月前
|
项目管理
类与类之间的协作模式问题之中介者模式在项目管理中有什么作用
类与类之间的协作模式问题之中介者模式在项目管理中有什么作用
|
3月前
|
存储 缓存 Java
|
4月前
软件复用问题之复用性风险是如何定义的
软件复用问题之复用性风险是如何定义的
|
6月前
|
设计模式 关系型数据库 Java
顺畅的职责传递-用责任链模式优化决策流程
本文首先通过经典场景展示了不使用设计模式时的问题与痛点。接着,引入责任链模式,详细讲解了其定义、解决问题的方式、结构图及工作原理,并通过重构示例展示了该模式如何解决原有痛点。最后,对责任链模式的优势、缺点以及在实际应用中可能遇到的挑战和限制进行了总结。责任链模式通过解耦请求发送者和接收者,提供了灵活的请求处理机制,适用于多个处理者按顺序处理请求的场景。然而,该模式也可能导致请求得不到处理或性能下降等问题,需在实际应用中权衡利弊。
252 0
顺畅的职责传递-用责任链模式优化决策流程
|
6月前
|
设计模式 消息中间件 存储
揭秘中介者模式-如何优雅地管理对象间的沟通
本文深入探讨了中介者模式在软件设计中的应用。中介者模式,作为一种行为型设计模式,通过引入中介者对象有效管理对象间的复杂交互,降低了系统的耦合度。文章详细分析了该模式的优点,如提高系统的灵活性和可维护性,同时也指出了其面临的挑战和局限,如中介者可能变得庞大难以维护、动态性处理复杂等。在使用中介者模式时,需要权衡利弊,合理设计中介者类,并持续维护系统的可扩展性和可维护性。总之,中介者模式为软件设计提供了一种有效的解耦和协调交互的机制,但需要根据具体场景和需求谨慎选择和应用。通过合理使用中介者模式,可构建更...
171 0
揭秘中介者模式-如何优雅地管理对象间的沟通
|
6月前
|
设计模式 缓存 编译器
【C/C++ 设计模式应用】精细化职责与灵活性:C++中的发送接口和数据转换基类设计
【C/C++ 设计模式应用】精细化职责与灵活性:C++中的发送接口和数据转换基类设计
114 0
|
设计模式 前端开发 Java
职责驱动设计以及状态模式的变化
职责驱动设计以及状态模式的变化
职责驱动设计以及状态模式的变化
|
架构师 数据可视化 领域建模
为什么你应该关心领域模型?
领域模型是DDD的核心,更是业务的深入认知
1887 0
为什么你应该关心领域模型?
|
SQL
封装与职责分离的开发思维
封装与职责分离的开发思维
116 0