TypeScript | 设计模式16 -责任链模式

554 阅读3分钟

这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

责任链模式

是一种行为设计模式,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。主要为了避免请求发送者与多个请求处理者耦合在一起。

模式结构

  • 抽象处理者: 定义了一个处理请求的接口,包含抽象处理方法和一个后继连接
  • 具体处理者:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
  • 客户端:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。
​
​
/** 抽象处理角色 
 *  仅定义一个抽象处理方法,和下一个处理者
 * */ 
abstract class Handler {
  public next: Handler;
  constructor(next: Handler) {
    this.next = next;
  }
​
  handlerRequest(request: string): void {}
}
​
​
/** 具体处理者1 **/
class ConHandler1 extends Handler {
  constructor(next: Handler) {
    super(next);
  }
  handlerRequest(request: string) {
    if (request == "first") {
      console.log("处理者1 开始处理");
    } else {
      if (this.next != null) {
        console.log('处理者1无法处理')
        this.next.handlerRequest(request);
      } else {
        console.log("无人处理该请求");
      }
    }
  }
}
​
/** 具体处理者2 **/
class ConHandler2 extends Handler {
  constructor(next: Handler) {
    super(next);
  }
​
  handlerRequest(request: string) {
    if (request == "second") {
      console.log("处理者2 开始处理");
    } else {
      if (this.next != null) {
        console.log('处理者2无法处理')
        this.next.handlerRequest(request);
      } else {
        console.log("无人处理该请求");
      }
    }
  }
}
​
(() => {
  const hdn: Handler = null;
  const handler2 = new ConHandler2(hdn);
  const handler1 = new ConHandler1(handler2);
​
  handler1.handlerRequest("first");
  handler1.handlerRequest("second");
  handler1.handlerRequest("econd");
})());

主要优点

  • 降低耦合度,增强系统的可扩展性,该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息
  • 增强了给对象指派职责的灵活性
  • 责任链简化了对象的连接,每个对象只需保持一个指向其后继者的引用,无需保持其他处理者的引用
  • 责任划分,每个类只处理自己该处理的工作,非自己责任则传递给下个对象处理,符合单一职责远离

适用场景

现实场景中,一个CRM系统的采购审批流程,OA系统的请假流程需要多层级部门的审批,请求的天数不同,不同领导审批权限不同,所以通过责任链模式,抽象出一个流程然后根据不同的请求去使用具体的处理者进行处理

  • 多个对象可以处理一个请求,但具体由哪个对象处理该请求在运行时自动确定
  • 可动态确定指定一组处理请求,或添加新的处理者
  • 需要在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求