( 十八 )、 设计模式 之 责任链模式(Chain of Responsibility)
( 十八 )、 设计模式 之 责任链模式(Chain of Responsibility)
1、简介
1、定义: 顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递。
一个请求先经过A处理器处理,然后再把请求传递给B处理器,B处理器处理完后再传递给C处理器,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责,所以叫作职责链模式。
要注意在标准的职责链模式中,只要有对象处理了请求,这个请求就到此为止不再被传递和处理了。如果要变形使用职责链,就可以让这个请求继续传递,每个职责对象对这个请求进行一定的功能处理,从而形成一个处理请求的功能链(如 Web应用中的过滤器链)。
2、责任链模式结构说明
- 职责的抽象类(AbstractHandler): 通常在这里定义处理请求的方法,并引用后继链。
- 具体的职责类(ConcreteHandler): 实现对在它职责范围内请求的处理,如果不处理,就继续转发请求给后继者处理。
- 职责链的客户端(Client): 向链上的具体处理对象提交请求,让职责链负责处理。
3、代码实现
/**
* @Author dw
* @ClassName AbstractHandler
* @Description 职责抽象类,定义处理请求的方法
* @Date 2023/12/18 15:39
* @Version 1.0
*/
public abstract class AbstractHandler {
/**
* 持有后继的职责对象
*/
protected AbstractHandler successor;
/**
* 设置后继的职责对象
*
* @param successor 后继者
*/
public void setSuccessor(AbstractHandler successor) {
this.successor = successor;
}
/**
* 处理请求的方法,可以根据具体需要来选择是否传递参数
*/
public abstract void handleRequest();
}
/**
* @Author dw
* @ClassName ConcreteHandler
* @Description 具体的责任处理者
* @Date 2023/12/18 15:45
* @Version 1.0
*/
public class ConcreteHandler1 extends AbstractHandler {
/**
* 设置后继的职责对象
*
* @param successor 后继者
*/
@Override
public void setSuccessor(AbstractHandler successor) {
super.setSuccessor(successor);
}
/**
* 处理请求的方法,可以根据具体需要来选择是否传递参数
*/
@Override
public void handleRequest() {
// 根据某些条件来判断是否属于自己处理的职责范围
// 判断条件比如:从外部传入的参数,或者这里主动去获取的外部数据。如从数据库中获取等,下面这句话只是个示意:
boolean someCondition = false;
if (someCondition) {
// 如果属于自己处理的职责范围,就在这里处理请求
System.out.println("ConcreteHandler1 handle request");
} else {
// 如果不属于自己处理的职责范围,那就判断是否还有后继的职责对象
// 如果有,就转发请求给后继的职责对象。如果没有,什么都不做,自然结束
if (this.successor != null) {
this.successor.handleRequest();
}
}
}
}
/**
* @Author dw
* @ClassName Client
* @Description 职责链的客户端
* @Date 2023/12/18 15:55
* @Version 1.0
*/
public class Client {
public static void main(String[] args) {
// 先要组装职责链
AbstractHandler h1 = new ConcreteHandler1();
// 这里的ConcreteHandler2 和 ConcreteHandler1 结构一致
// AbstractHandler h2 = new ConcreteHandler2();
// h1.setSuccessor(h2);
// 然后提交请求
h1.handleRequest();
}
}
4、责任链的优缺点
优点
1、请求者和接收者松散耦合: 在职责链模式中,请求者并不知道接收者是谁,也不知道具体如何处理,请求者只是负责向职责链发出请求就可以了。而每个职责对象也不用管请求者或者是其他的职责对象,只负责处理自己的部分,其他的就交给其他的职责对象去处理。也就是说,请求者和接收者是完全解耦的。
2、动态组合职责: 职责链模式会把功能处理分散到单独的职责对象中,然后在使用的时候,可以动态组合职责形成职责链,从而可以灵活地给对象分配职责,也可以灵活地实现和改变对象的职责。
5、责任链模式在Spring中的应用
- Spring的异常处理:Spring的异常处理机制采用了责任链模式,通过定义不同的异常处理器,将不同的异常类型传递给不同的处理器进行处理。这样可以使得异常处理更加灵活和可配置。
- Spring的AOP实现:Spring的AOP实现也使用了责任链模式,通过定义不同的切面(Aspect),将请求依次传递给这些切面进行处理。这样可以使得代码更加清晰和易于维护。
- Spring的HandlerInterceptor:在Spring MVC框架中,可以使用HandlerInterceptor来拦截请求并处理请求。每个HandlerInterceptor都可以看作是一个处理器,通过责任链将请求依次传递给这些处理器进行处理。这样可以使得请求处理流程更加灵活和可配置。