背景知识:传统责任链模式
顾名思义,责任链模式为一个请求创建一系列接收者对象,这些接收对象仿佛组成了一条链,请求沿着这套链传递,直到处理完为止。此模式基于请求的类型将请求的发送方和接收方分离,从而避免请求的发送者和接收者之间的耦合关系。
这种模式是一种行为模式,在这种模式中,通常每个接收器都包含对另一个接收器的引用。如果一个对象不能处理请求,则它将相同的对象传递给下一个接收者。
传统的责任链模式,每当有需求需要新增接收器时,需要新建一个接收器这是肯定的,但同时也需要在链式处理中将新的接收器指定为上一个接收器的引用。
而使用策略模式替换责任链模式,只需要关注接收器本身即可,不再需要手动变更链式过程。下面介绍一个场景,订单详情信息查询,大家都知道订单信息往往会关联很多扩展信息,如果是面向过程的思维编码,后面任何一次改动,都可能危机全部。而只用设计模式拆分,则可以将后续的变更影响范围控制到最小的粒度。
下面废话不多说,直接上代码。首先是请求接收器的接口定义:
public interface OrderInfoBuildHanlder {
/**
* 是否匹配,匹配成功则执行对应策略
* @param orderContext
* @return
*/
boolean match(OrderContext orderContext);
/**
* 构建订单详情
* @param orderContext
* @param orderDetailDTO
*/
void buildOrderContent(OrderContext orderContext,OrderDetailDTO orderDetailDTO);
}
接收器实现类定义:(注意这里使用了@Order注解)
@Service
@Order(10)
public class ReceiptInfoBuildHanlder implements OrderInfoBuildHanlder {
@Autowired
private ReceiptOrderQueryService receiptOrderQueryService;
@Override
public boolean match(OrderContext orderContext) {
//业务判断是否执行
return orderContext.getReceiptOrder()!=null;
}
/**
* 构造订单详情信息
*/
@Override
public void buildOrderContent(OrderContext orderContext,OrderDetailDTO orderDetailDTO) {
ReceiptOrderInfo receiptOrder= receiptOrderQueryService.queryReceiptOrder(orderContext.getOrderUuid());
//转换回单信息到订单详情
buildReceiptOrderInfo(receiptOrder, orderDetailDTO);
}
}
订单信息服务主入口:
@Service
public class OrderDetailService {
@Autowired
List<OrderInfoBuildHanlder> orderInfoBuildHanlders;
public OrderDetailDTO buildOrderDetail(OrderContext orderContext) {
OrderDetailDTO orderDetail = new OrderDetailDTO();
// 我们在这里会把每个需要填充的信息都做一个填充()
orderInfoBuildHanlders.stream().filter(item -> item.match(orderContext))
.forEach(item -> item. buildOrderContent(orderContext, orderDetail));
return deliveryOrderDTO;
}
}
说明: 注意Spring的@Autowired和@Order注解配合,就可以确保hanlder执行顺序。
是不是感觉很不错,如果喜欢,你可以试试。
网友评论