记一次设计模式随笔

1. 有一个公共的代码处理逻辑

 1 private void linkReceipt(LinkSendNotifyDTO linkSendNotifyDTO) {
 2         if (linkSendNotifyDTO.getStatus() != null && linkSendNotifyDTO.getStatus()) {
 3             //==================1、处理业务类型定制化业务==================
 4             BizHandler bizHandler = BizHandlerFactory.getInstance(linkSendNotifyDTO.getChannelBizType());
 5             bizHandler.doReceipt(linkSendNotifyDTO.getOrderId(), linkSendNotifyDTO.getData());
 6 
 7             //==================2、处理某些渠道定制化业务==================
 8             ChannelHandler channelHandler = ChannelHandlerFactory.getInstance(linkSendNotifyDTO.getNodeMapping());
 9             channelHandler.doReceipt(linkSendNotifyDTO);
10         }
11 
12         //==================3、处理公共逻辑==================
13         Integer status = null;
14         Integer recordStatus = null;
15         if (linkSendNotifyDTO.getStatus() != null && linkSendNotifyDTO.getStatus()) {
16             status = ReceiptStatus.ACCEPTED.getCode();
17             recordStatus = DocChannelStatus.SUCCESS.getCode();
18 
19         } else {
20             status = ReceiptStatus.REFUSED.getCode();
21             recordStatus = DocChannelStatus.FAIL.getCode();
22         }
23 
24         String channelCode = linkSendNotifyDTO.getNodeMapping();
25 
26         if (!orderLinkServiceConfig.getOrderLinkChannelCodeDocChannelRecordBlocklist().contains(channelCode)) {
27             //3.1、更新单证发送记录状态29         }
30 
31         if (!orderLinkServiceConfig.getOrderLinkChannelCodeDocumentEventBlocklist().contains(channelCode)) {
32             //3.2、订单标准事件入库36         }
37 
38         if (!orderLinkServiceConfig.getOrderLinkChannelCodeDingdingBlocklist().contains(channelCode)) {
39             //3.3、钉钉消息43         }
44     }

抽象的Handler,实现自定义自己的策略

//1、处理业务类型定制化业务
public abstract class BizHandler {
    public abstract void doReceipt(Long orderId, String bizData);
}

//2、处理某些渠道定制化业务
public abstract class ChannelHandler {
    public abstract void doReceipt(LinkSendNotifyDTO linkSendNotifyDTO);
}

使用工厂方法获取策略

 1 public class ChannelHandlerFactory implements ApplicationContextAware {
 2     private static ApplicationContext context;
 3     private static final Map<String, Class<? extends ChannelHandler>> map = new HashMap<>();
 4 
 5     static {
 6         map.put("booking_sinko_rpa", SinkoBookingChannelHandler.class);
 7         map.put("booking_sitc_rpa", SitcBookingChannelHandler.class);
 8         map.put("surcharge_maersk_rpa", MaerskSurchargeChannelHandler.class);
 9     }
10 
11     public static ChannelHandler getInstance(String channelCode) {
12         return map.containsKey(channelCode) ? context.getBean(map.get(channelCode)) : context.getBean(DefaultChannelHandler.class);
13     }
14 
15     @Override
16     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
17         context = applicationContext;
18     }
19 }

 

ps.具体实现的策略

 1 public class SinkoBookingChannelHandler extends ChannelHandler {
 2 
 3     @Autowired
 4     private OrderRabbitMQSender orderRabbitMQSender;
 5     private static String SINKO_EMAIL_EXCHANGE = "SinkoEmailExchange";
 6 
 7     @Override
 8     public void doReceipt(LinkSendNotifyDTO linkSendNotifyDTO) {
 9         String bizData=linkSendNotifyDTO.getData();
10         Long orderId=linkSendNotifyDTO.getOrderId();
11         if (StringUtils.isBlank(bizData)) return;
12         BookingResultVO data = JSONObject.parseObject(bizData, BookingResultVO.class);
13         String bookingNumber = StringUtil.removeNotLetterNumber(data.getBookingNo());
14         if (StringUtils.isBlank(bookingNumber)) return;
15         OrderReceiptDTO orderReceiptDTO = OrderReceiptDTO.builder()
16                 .orderId(orderId)
17                 .bookingNumber(StringUtils.replaceAll(bookingNumber, "[^a-zA-Z0-9]", ""))
18                 .build();
19         String json = JSONObject.toJSONString(orderReceiptDTO);
20         YQNExecutor.execute(new YQNRunnable() {
21             @Override
22             public void runBiz() {
23                 orderRabbitMQSender.send(SINKO_EMAIL_EXCHANGE, "", json);
24                 Loggers.BIZ.info("LinkMQReceiptConsumer-长锦订舱成功,发送邮件" + orderId + "json:" + json);
25             }
26         });
27     }
28 }

 

问题1:自定义策略被一个if条件包裹,但是有些策略执行条件不一样

问题2:有个别策略在公共逻辑处理上有点小不同,不想使用if else做特殊处理

问题3:不想使用多个黑名单的方式过滤策略使用公共逻辑

==》使用模板方法

 1 public abstract class ChannelTemplateHandler {
 2     //自定义校过滤
 3     public boolean before(Boolean status) {
 4         return status == null ? false : status;
 5     }
 6 
 7     public abstract void doReceipt(LinkSendNotifyDTO linkSendNotifyDTO);
 8 
 9     public void after(LinkSendNotifyDTO linkSendNotifyDTO) {
10         this.updateDocChannelRecordStatus(linkSendNotifyDTO);
11         this.saveDocumentEvent(linkSendNotifyDTO);
12         this.sendDingdingReminderNew(linkSendNotifyDTO);
13     }
14 
15     //更新单证发送记录状态
16     public void updateDocChannelRecordStatus(LinkSendNotifyDTO linkSendNotifyDTO) {
17         //do something
18     }
19 
20     //订单标准事件入库
21     public void saveDocumentEvent(LinkSendNotifyDTO linkSendNotifyDTO) {
22         //do something
23     }
24 
25     //钉钉消息
26     public void sendDingdingReminderNew(LinkSendNotifyDTO linkSendNotifyDTO) {
27         //do something
28     }
29 }

 

posted @ 2020-06-19 14:41  鸡犬相闻  阅读(174)  评论(0编辑  收藏  举报