责任链模式是一种行为设计模式,它将请求的发送者和接收者解耦,以便多个对象有机会处理请求。在此模式中,请求沿着处理链传递,直到对象能够处理它。
本文将详细介绍责任链模型的概述、应用场景和代码示例,以帮助读者更好地理解和应用该模型。
责任链模式的核心思想是解耦请求的发送者和接收者,让多个对象都有机会处理请求。在责任链模型中,请求沿着处理链传递,每个处理器都有机会处理该请求。如果一个处理器无法处理该请求,则该请求将被传递到下一个处理器,直到下一个处理器可以处理它为止。
责任链模型包括以下角色:
优点:
缺点:
责任链模式广泛应用于许多不同的应用场景。下面列出了一些常见的应用场景:
Java责任链模式的实现方式有很多种,包括基于接口、基于抽象类、基于注解等。下面将详细介绍基于接口的常用实现方法以下。
Java
基于接口的实现是通过定义处理请求的接口。每个处理器都实现这个接口,并在自己的实现中决定是否处理该请求并将请求传递给下一个处理器。
首先我们定义一个处理请求的接口Handler以及请求输入参数Request:
Handler
Request
公共 接口 处理程序 { voidhandleRequest(请求请求); }公共班级请求{ private字符串类型; //省略 getter 和 setter}
然后,我们创建3个特定的处理器类来实现这个接口。在具体处理器类的实现中,我们首先判断是否能够处理该请求。如果可以的话,处理它;否则,将请求传递给下一个。处理程序。代码如下:
公共 类 ConcreteHandlerA 实现 处理程序 { 私人 处理程序后继者; public void setSuccessor(处理程序后继者) { 这个.后继=后继者; } 公共void handleRequest (请求请求) { if (request.getType().equals("A")) { // 处理请求的逻辑 } 否则 if(后继!=null){ successor.handleRequest(请求); } }}公共 班级 ConcreteHandlerB 实现 Handler { 私有 处理程序继任者; 公共 void 设置后继者(处理程序后继者) { 这个.后继者=后继者; } public void handleRequest(请求请求) { if(request.getType().equals() "B")) { //处理请求的逻辑 } else if(后继者!= null) { successor.handleRequest(request); } }}公共 类 ConcreteHandlerC 实现 Handler { private Handler 继承者; public void 设置后继者(处理程序后继者) { 这个.后继者=后继者; } 公共 空 handleRequest(请求请求) { if(request.getType().e quals("C")) { // 处理请求的逻辑 } else if(后继!= null) { successor.handleRequest(request); } }}
接下来我们创建一个客户端类Client,用于创建handler对象,形成责任链的结构:
公共 类 客户端 { 公共 静态 空 main(String[] args) { Handler handlerA = new ConcreteHandler A(); Handler handlerB = new ConcreteHandlerB (); 处理程序 handlerC = new ConcreteHandlerC(); handlerA.setSuccessor(handlerB); " 并发 被发送到第一个处理器 请求请求 = new 请求("A"); handlerA.handleRequest(请求); }}
在客户端类中,我们创建具体的处理程序对象,并通过setSuccessor()方法将它们形成责任链结构。然后,创建一个请求对象并将请求发送到第一个处理程序。
setSuccessor()
基于接口的实现方式简单直观,每个处理器只需要实现一个接口。但其缺点是,如果责任链较长,需要创建多个handler对象,增加了系统的复杂度和资源消耗。下面基于spring框架实现一个高级版的责任链模型。
spring
在实际开发中,一个请求会在多个处理器之间流动,每个处理器都可以处理该请求。
假设我们有一个使用Spring框架开发的订单处理系统。订单需要依次经过订单审核、库存处理、付款处理。如果某个处理环节无法处理该订单,则终止处理并返回错误信息。只有当每个处理者都完成了请求处理后,才能下单成功。
首先,我们定义一个订单类Order:
Order
@Data@AllArgsConstructorpublicclassorderNo { 私有 字符串 orderNumber; private String paymentMethod; private boolean库存库存; 私人字符串运输地址;}
然后,我们定义一个抽象订单处理类OrderHandler:
OrderHandler
公共 抽象 类 OrderHandler {公共摘要void处理订单(下单顺序);}
接下来我们创建一个具体的订单处理器类,继承于抽象订单处理器类,实现相应的方法,并注册到Spring,
Spring
@Componentpublic class CheckOrderHandler 扩展 订单处理程序 { public void 处理订单(订单顺序){ if (StringUtils.isBlank(order.getOrderNo()) ){ 抛出 新运行时异常() "订单号不能为空" ); (order.getPrice().compareTo(BigD)十进制.ONE) <= 0) { 投掷 new RuntimeException("订单金额不能小于或等于 0" ) ; throw new RuntimeException ("送货地址不能为空"); } } System.out.println ("订单参数验证通过" ); }}@Componentpublic 类StockHandler 扩展 订单处理程序 { 公共 void 处理订单(订单顺序) { if (!order.isStockAvailability()) { 扔 新 RuntimeException("订单库存不足"); ); }} @Component公共 类AliPaymentHandler 扩展 OrderHandler { 公共 空 手柄或der(订购顺序){ if (!order.getPaymentMethod().equals("支付宝")) { 投掷 new RuntimeException("除不支持支付宝"); } System.out.println("支付宝预购成功"); 在具体订单处理器类的实现中,CheckOrderHandler负责检查订单参数,StockHandler负责库存扣减,AliPaymentHandler 负责制作预订时下单时,各个处理器的逻辑是相互独立的。别干涉。 最后创建订单生产链BuildOrderChain,用于形成责任链的链式处理结构:@Componentpublic classBuildOrderChain { @Autowired private AliPaymentHandler aliPaymentHandler ; @Autowired 私有CheckOrderHandler checkOrderHandler; @Autowired 私人 StockHandler stockHandler; 列表列表 = new ArrayList<>(); @PostConstruct public void init() { // 1. 检查订单参数 list.add(checkOrderHandler); // 2. 扣减库存 list.add( stockHandler); // 3. 支付宝预下单 list.add(aliPaymentHandler); } 公共 空 doFilter(订单订单) { for(OrderHandler orderHandler : 这个.list) { orderHandler.handleOrder(order) ; } }}在订单生产链BuildOrderChain类中,我们在注释init()下传递@PostConstruct 初始化方法,在代码顺序A中分配特定的顺序处理器形成责任链的结构。然后使用doFilter(order)方法遍历处理器集合并按顺序处理。 运行代码, @Slf4j@springboot测试@RunWith(SpringRunner) .班级)公共 类 订单链测试 { @Auto有线私有BuildOrderChain buildOrderChain;@Test公共void测试(){ 下单下单 = 新下单( "123456","支付宝", true, “长沙”, newBigDecimal( "100")); BuildOrderChain.doFilter(order); ---------订单参数验证通过库存扣除成功支付宝预购成功 可以看到订单依次经过验证处理器、库存处理器和支付处理器处理,直到最终处理完整个订单。 比如我们的订单是虚拟无限库存商品,我们不需要进行库存扣减,那么我们可以直接新建一个VirtualGoodsOrderChain虚拟商品订单生产链类,代码为接下来是, @Componentpublic class 虚拟商品订单链 { @Autowired private AliPaymentHandler aliPaymentHandler ) list = newArrayList<>(); @PostConstruct 公共 void init() { // 1.查看订单参数 D List.add(CheckorderHandler); // 2 支付宝预购 list.add(ali paymenthandler); doFilter(订单订单)for(OrderHandler orderHandler : this.list) { orderHandler .handleOrder(order); 运行代码:@TestpublicvoidvirtualOrderTest() { 订单订单 = 新 订单( "123456", "支付宝", true, “长沙”, new BigDecimal(“100”); -------------------订单参数验证通过支付宝预购成功
void 处理订单(订单顺序) { if (!order.isStockAvailability()) { 扔 新 RuntimeException("订单库存不足"); ); }} @Component公共 类AliPaymentHandler 扩展 OrderHandler { 公共 空 手柄或der(订购顺序){ if (!order.getPaymentMethod().equals("支付宝")) { 投掷 new RuntimeException("除不支持支付宝"); } System.out.println("支付宝预购成功"); 在具体订单处理器类的实现中,CheckOrderHandler负责检查订单参数,StockHandler负责库存扣减,AliPaymentHandler 负责制作预订时下单时,各个处理器的逻辑是相互独立的。别干涉。 最后创建订单生产链BuildOrderChain,用于形成责任链的链式处理结构:@Componentpublic classBuildOrderChain { @Autowired private AliPaymentHandler aliPaymentHandler ; @Autowired 私有CheckOrderHandler checkOrderHandler; @Autowired 私人 StockHandler stockHandler; 列表列表 = new ArrayList<>(); @PostConstruct public void init() { // 1. 检查订单参数 list.add(checkOrderHandler); // 2. 扣减库存 list.add( stockHandler); // 3. 支付宝预下单 list.add(aliPaymentHandler); } 公共 空 doFilter(订单订单) { for(OrderHandler orderHandler : 这个.list) { orderHandler.handleOrder(order) ; } }}在订单生产链BuildOrderChain类中,我们在注释init()下传递@PostConstruct 初始化方法,在代码顺序A中分配特定的顺序处理器形成责任链的结构。然后使用doFilter(order)方法遍历处理器集合并按顺序处理。 运行代码, @Slf4j@springboot测试@RunWith(SpringRunner) .班级)公共 类 订单链测试 { @Auto有线私有BuildOrderChain buildOrderChain;@Test公共void测试(){ 下单下单 = 新下单( "123456","支付宝", true, “长沙”, newBigDecimal( "100")); BuildOrderChain.doFilter(order); ---------订单参数验证通过库存扣除成功支付宝预购成功 可以看到订单依次经过验证处理器、库存处理器和支付处理器处理,直到最终处理完整个订单。 比如我们的订单是虚拟无限库存商品,我们不需要进行库存扣减,那么我们可以直接新建一个VirtualGoodsOrderChain虚拟商品订单生产链类,代码为接下来是, @Componentpublic class 虚拟商品订单链 { @Autowired private AliPaymentHandler aliPaymentHandler ) list = newArrayList<>(); @PostConstruct 公共 void init() { // 1.查看订单参数 D List.add(CheckorderHandler); // 2 支付宝预购 list.add(ali paymenthandler); doFilter(订单订单)for
void 处理订单(订单顺序) { if (!order.isStockAvailability()) { 扔 新 RuntimeException("订单库存不足"); ); }} @Component公共 类AliPaymentHandler 扩展 OrderHandler { 公共 空 手柄或der(订购顺序){ if (!order.getPaymentMethod().equals("支付宝")) { 投掷 new RuntimeException("除不支持支付宝"); } System.out.println("支付宝预购成功"); 在具体订单处理器类的实现中,CheckOrderHandler负责检查订单参数,StockHandler负责库存扣减,AliPaymentHandler 负责制作预订时下单时,各个处理器的逻辑是相互独立的。别干涉。 最后创建订单生产链BuildOrderChain,用于形成责任链的链式处理结构:@Componentpublic classBuildOrderChain { @Autowired private AliPaymentHandler aliPaymentHandler ; @Autowired 私有CheckOrderHandler checkOrderHandler; @Autowired 私人 StockHandler stockHandler; 列表列表 = new ArrayList<>(); @PostConstruct public void init() { // 1. 检查订单参数 list.add(checkOrderHandler); // 2. 扣减库存 list.add( stockHandler); // 3. 支付宝预下单 list.add(aliPaymentHandler); } 公共 空 doFilter(订单订单) { for(OrderHandler orderHandler : 这个.list) { orderHandler.handleOrder(order) ; } }}在订单生产链BuildOrderChain类中,我们在注释init()下传递@PostConstruct
CheckOrderHandler
StockHandler
AliPaymentHandler
最后创建订单生产链BuildOrderChain,用于形成责任链的链式处理结构:
BuildOrderChain
@Componentpublic classBuildOrderChain { @Autowired private AliPaymentHandler aliPaymentHandler ; @Autowired 私有CheckOrderHandler checkOrderHandler; @Autowired 私人 StockHandler stockHandler; 列表列表 = new ArrayList<>(); @PostConstruct public void init() { // 1. 检查订单参数 list.add(checkOrderHandler); // 2. 扣减库存 list.add( stockHandler); // 3. 支付宝预下单 list.add(aliPaymentHandler); } 公共 空 doFilter(订单订单) { for(OrderHandler orderHandler : 这个.list) { orderHandler.handleOrder(order) ; } }}
订单生产链BuildOrderChain类中,我们在注释init()下传递@PostConstruct
@PostConstruct
doFilter(order)
运行代码,
@Slf4j@springboot测试@RunWith(SpringRunner) .班级)公共 类 订单链测试 { @Auto有线私有BuildOrderChain buildOrderChain;@Test公共void测试(){ 下单下单 = 新下单( "123456","支付宝", true, “长沙”, newBigDecimal( "100")); BuildOrderChain.doFilter(order); ---------订单参数验证通过库存扣除成功支付宝预购成功
可以看到订单依次经过验证处理器、库存处理器和支付处理器处理,直到最终处理完整个订单。
比如我们的订单是虚拟无限库存商品,我们不需要进行库存扣减,那么我们可以直接新建一个VirtualGoodsOrderChain虚拟商品订单生产链类,代码为接下来是,
VirtualGoodsOrderChain
@Componentpublic class 虚拟商品订单链 { @Autowired private AliPaymentHandler aliPaymentHandler ) list = newArrayList<>(); @PostConstruct 公共 void init() { // 1.查看订单参数 D List.add(CheckorderHandler); // 2 支付宝预购 list.add(ali paymenthandler); doFilter(订单订单)for
运行代码:
@TestpublicvoidvirtualOrderTest() { 订单订单 = 新 订单( "123456", "支付宝", true, “长沙”
总体来说,责任链模型适用于处理步骤较多、每个处理步骤都有独立的逻辑或条件、需要灵活组合和扩展的场景。通过责任链模型,可以将复杂的处理逻辑拆分为多个独立的处理步骤,并且处理步骤的顺序可以动态组合和调整,从而提高系统的灵活性和可维护性。希望本文能够帮助读者理解和应用责任链模型,提高软件设计和开发能力。
·完·
因公众号更改了推送规则,关注公众号首页点击右上角“设为明星”》第一时间获取博主精彩技术资讯
往期原创热门文章推荐:
设计模式模板方法模式
一套前后端全开源的H5商城送给你
什么是好代码/坏代码?给普通人看的图例
推荐算法在商城系统中实现
使用策略模式重构 if/elseif/elseif