目录
前言
何为责任链
三个角色
类图
代码结构
结果
“纯”和“不纯”责任链
上一篇我们讲到了策略模式【设计模式第一弹】 ,实际上我理解是责任链模式跟策略模式在某种程度上是类似的,毕竟它们也是基于接口或者基于抽象类编程的,只是在具体的实现类的使用上面有点不太一样。
策略模式:更多是通过上下文去动态决定选用哪一种策略,关键在于只选取其中一种。
责任链模式:更多是通过上下文去动态决定选用一组策略,并且通过类似链表的组合方式进行具体策略的编排,关键在于组合编排。
哔哩吧啦说了一通,我们还是直接进入主题吧。
某度的定义就是:它是一种设计模式,它包含了一些命令对象和一系列的处理对象。每一个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。
是不是隐晦难懂?
说得直白又接地气一点,就是说:有一个对象要处理,该模式通过把一系列的责任节点通过链式串联起来,每个责任节点负责对对象进行不同维度的处理,同时每个节点是知道它后面的责任节点的,然后该对象通过链式传递被不同责任节点进行处理。它的优越的地方体现在客户端不需要知道谁去处理这个对象,这样就可以根据不同的对象的情况动态组装责任链,把客户端和服务端进行了解耦。
当然,这里有所谓的“纯”责任链或“不纯”责任链两种,这里后面再做介绍。
优点 | 1、可以把请求与处理进行解耦,降低耦合性;另外,处理者之间也是解耦的; 2、责任链编排可以是动态绑定、动态更新,相对比较灵活; |
缺点 | 1、容易因为设置不当导致死循环; 2、调试比较麻烦。 |
1、抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
2、具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
3、具体上下文(Context)角色:用于编排整个链条。具体有以下几种做法建立链条:
话不多说,这里先上图。
第一:定义抽象处理类及所有的具体实现类(每个类负责其中一部分责任)
public abstract class Handler { // 指向下一个处理器 public Handler nextHandler; public abstract void processRequest(); }
public class PackagingHandler extends Handler{ @Override public void processRequest() { System.out.println("可口可乐正在被打包装。"); if (this.nextHandler == null){ System.out.println("可口可乐流水线处理完。"); }else{ this.nextHandler.processRequest(); } } }
public class CleaningHandler extends Handler { @Override public void processRequest() { System.out.println("可口可乐瓶子正在被清洗。"); if (this.nextHandler == null){ System.out.println("可口可乐流水线处理完。"); }else{ this.nextHandler.processRequest(); } } }
public class FillingHandler extends Handler { @Override public void processRequest() { System.out.println("可口可乐正在被灌装。"); if (this.nextHandler == null){ System.out.println("可口可乐流水线处理完。"); }else{ this.nextHandler.processRequest(); } } }
第二:通过上下文类构建链条
public class CocacolaChain { /** * 构建流水线链条 */ public Handler buildChain(){ /** * 创建 handler实例,这里为了简单演示原理,不使用spring的注入 */ Handler handler1 = new CleaningHandler(); Handler handler2 = new FillingHandler(); Handler handler3 = new PackagingHandler(); /** * 为每个handler之间创建链条:handler1 -> handler2 -> handler3 */ handler1.nextHandler = handler2; handler2.nextHandler = handler3; return handler1; } }
第三:编写service用于给controller调用从而对外提供REST接口,这里直接通过main方法演示。
@Service public class CocacolaService { public void createCola() { /** * 创建责任链 */ CocacolaChain cocacolaChain = new CocacolaChain(); Handler handler = cocacolaChain.buildChain(); // 开始处理 handler.processRequest(); } public static void main(String[] args){ CocacolaService cocacolaService = new CocacolaService(); cocacolaService.createCola(); } }
5.1.14.RELEASE.jar;C:\Users\justyman\.m2\repository\org\springframework\spring-jcl\5.1.14.RELEASE\spring-jcl-5.1.14.RELEASE.jar" com.mycompany.pipeline.service.CocacolaService
可口可乐瓶子正在被清洗。
可口可乐正在被灌装。
可口可乐正在被打包装。
可口可乐流水线处理完。Process finished with exit code 0
从上面的处理结果来看,每个处理者负责一部分的责任, 这是“不纯”的责任链,即某个处理者既要处理请求,又要把请求传递给下一个处理者继续处理。
那什么是“纯”责任链?纯的责任链实际上就是一个请求只会被一个处理者处理。
今天就先总结到这里,下一个我们讲一下我之前用的观察者模式,相信开发人应该对Observer和Observable不陌生吧。