20.行为型 - 责任链模式(ChainofResponsibility Pattern)

行为型 - 责任链模式(ChainofResponsibility Pattern)

在职责链模式中通常每个接收者都包含另一个接收者的引用,这样在处理请求时,如果自己无法处理该请求时就会把请求,传递给下一个接收者,依次类推直到最后。
通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

类似的:

  1. JS 中的事件冒泡;
  2. Servlet 中的 Filter;
  3. Spring 过滤链就是典型的责任链模式;

意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止

主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

例: 日志框架, 一个日志记录对象只处理自己等级的日志, 这时候可以把所有等级的日志记录器串联起来, 组成责任链, 统一接受记录所有等级的日志记录请求;

UML类图

Pasted image 20231205210811

代码实例

1.定义抽象日志记录器

(所有等级日志记录器, 继承自它)

abstract class AbsLoger{
	public final static int INFO = 1;
	public final static int DEBUG = 2;
	public final static int ERROR = 3;
	
	int leve;
	//下一个处理对象
	AbsLoger nextLoger;
	public void setNextChina( AbsLoger nextLoger){
		this.nextLoger = nextLoger;
	}
	
	public void logMes(int leve, String mes){
		//处理自己等级的
		if (this.leve == leve){
			write(mes);
		}
		//调用下一个处理对象
		if(this.nextLoger != null){
			nextLoger.logMes(leve, mes);
		}
		
	}
	
	//具体处理的方法, 交给实现类
	abstract void write(String mes);
}

2.具体各等级的实现

//实现记录器(error 等级)

class ErrorLoger extends AbsLoger{
	ErrorLoger(){
		this.leve=AbsLoger.ERROR;
	}
	@Override
	void write(String mes) {
		System.out.println("这是处理错误级别的: "+ mes);
	}
}
//实现记录器(info 等级)
class InfoLoger extends AbsLoger{
	InfoLoger(){
		this.leve=AbsLoger.INFO;
	}
	@Override
	void write(String mes) {
		System.out.println("这是处理信息级别的: "+ mes);
	}
}
//实现记录器(debug 等级)
class DebugLoger extends AbsLoger{
	DebugLoger(){
		this.leve=AbsLoger.DEBUG;
	}
	@Override
	void write(String mes) {
		System.out.println("这是处理调试级别的: "+ mes);
	}
}

3.测试

测试


/**
   * 组成责任链 
   */
public static AbsLoger getChinaLoger(){
   AbsLoger errorLoger = new ErrorLoger();
   AbsLoger infoLoger = new InfoLoger();
   AbsLoger debugLoger = new DebugLoger();
   //组成责任链
   errorLoger.setNextChina(infoLoger);
   infoLoger.setNextChina(debugLoger);
   
   //注意 (就是一个单向链表, 所以要返回链头) 也就是 errorLoger 
   return errorLoger;
}


public static void main(String[] args) {
   AbsLoger loger = ChainOfResponsibilityPattern.getChinaLoger();
   loger.logMes(AbsLoger.DEBUG, "调试日志");
   loger.logMes(AbsLoger.INFO, "信息日志");
   loger.logMes(AbsLoger.ERROR, "错误日志");
}

责任链模式总结

关键角色

  1. 抽象责任处理角色
  2. 具体责任处理角色 (注意, 它持有下一个处理者)

责任链模式优缺点

职责链模式的优点

  • 降低了对象之间的耦合度
    该模式降低了请求发送者和接收者的耦合度。

  • 增强了系统的可扩展性
    可以根据需要增加新的请求处理类,满足开闭原则。

  • 增强了给对象指派职责的灵活性
    当工作流程发生变化,可以动态地改变链内的成员或者修改它们的次序,也可动态地新增或者删除责任。

  • 责任链简化了对象之间的连接
    一个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。

  • 责任分担
    每个类只需要处理自己该处理的工作,不能处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。

职责链模式的缺点:

  • 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
  • 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
  • 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。

责任链模式适用场景

责任链模式常见的使用场景有以下几种情况。

  • 在运行时需要动态使用多个关联对象来处理同一次请求时。比如,请假流程、员工入职流程、编译打包发布上线流程等。
  • 不想让使用者知道具体的处理逻辑时。比如,做权限校验的登录拦截器。
  • 需要动态更换处理对象时。比如,工单处理系统、网关 API 过滤规则系统等。
  • 职责链模式常被用在框架开发中,用来实现框架的过滤器、拦截器功能,让框架的使用者在不修改源码的情况下,添加新的过滤拦截功能.
posted @ 2026-02-13 23:17  daidaidaiyu  阅读(1)  评论(0)    收藏  举报