先看下面Web控制器类里的这个方法,请注意for循环里的 oneRecord 变量。
public class SmsReplyMsgNotify { private CreateSmsModel createSmsModel; private SmsDeliverManager smsDeliverManager; private SmsDeliverBizService smsDeliverBizService; /** * 处理短信上行通知 * @param request */ "/deliverMsg/{supplierFlag}") ( public String processRequest( ("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。
public class SmsDeliverBizService { private SmsReportManager smsReportManager; 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 里。
这样改动后,使得代码结构更加清晰、各层职责划分更为明确。