方法的职责

简介: 【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天前
|
设计模式 存储 算法
设计模式——责任链
OA系统的采购审批项目、职责链模式基本介绍、职责链模式解决 OA 系统采购审批项目
设计模式——责任链
|
30天前
|
项目管理
类与类之间的协作模式问题之中介者模式在项目管理中有什么作用
类与类之间的协作模式问题之中介者模式在项目管理中有什么作用
|
29天前
|
存储 缓存 Java
|
4月前
|
设计模式 Java Spring
责任链设计模式详解
该内容主要介绍了如何使用Java实现责任链模式。
51 4
|
4月前
|
设计模式 消息中间件 存储
揭秘中介者模式-如何优雅地管理对象间的沟通
本文深入探讨了中介者模式在软件设计中的应用。中介者模式,作为一种行为型设计模式,通过引入中介者对象有效管理对象间的复杂交互,降低了系统的耦合度。文章详细分析了该模式的优点,如提高系统的灵活性和可维护性,同时也指出了其面临的挑战和局限,如中介者可能变得庞大难以维护、动态性处理复杂等。在使用中介者模式时,需要权衡利弊,合理设计中介者类,并持续维护系统的可扩展性和可维护性。总之,中介者模式为软件设计提供了一种有效的解耦和协调交互的机制,但需要根据具体场景和需求谨慎选择和应用。通过合理使用中介者模式,可构建更...
84 0
揭秘中介者模式-如何优雅地管理对象间的沟通
|
4月前
|
设计模式 关系型数据库 Java
顺畅的职责传递-用责任链模式优化决策流程
本文首先通过经典场景展示了不使用设计模式时的问题与痛点。接着,引入责任链模式,详细讲解了其定义、解决问题的方式、结构图及工作原理,并通过重构示例展示了该模式如何解决原有痛点。最后,对责任链模式的优势、缺点以及在实际应用中可能遇到的挑战和限制进行了总结。责任链模式通过解耦请求发送者和接收者,提供了灵活的请求处理机制,适用于多个处理者按顺序处理请求的场景。然而,该模式也可能导致请求得不到处理或性能下降等问题,需在实际应用中权衡利弊。
117 0
顺畅的职责传递-用责任链模式优化决策流程
|
4月前
|
设计模式 缓存 编译器
【C/C++ 设计模式应用】精细化职责与灵活性:C++中的发送接口和数据转换基类设计
【C/C++ 设计模式应用】精细化职责与灵活性:C++中的发送接口和数据转换基类设计
89 0
|
设计模式 XML 存储
设计模式之责任链
设计模式之责任链
184 1
设计模式之责任链
|
设计模式 Java jenkins
一文带你玩转设计模式之「责任链」
对于已经工作了的小伙伴,你应该是见过"责任链"这种面向对象的设计模式的,还在上学的小伙伴也不用着急,你迟早会接触到的。本文旨在让小白同学和不太熟悉责任链的朋友能够迅速对这一设计模式有一个大致的了解。 在我们的工农业生产中,经常有这样的场景:一个任务、事务、流程等都需要很多不同的步骤,来完成不同的计算或者收集不同的数据。 为了维护一个比较复杂,有时甚至是对顺序敏感的任务流程,我们经常在代码的编写和设计上采用"责任链"设计模式。
163 1
一文带你玩转设计模式之「责任链」
|
设计模式
设计模式是什么鬼(责任链)
设计模式是什么鬼(责任链)
设计模式是什么鬼(责任链)