跳至主要內容

责任链模式

约 634 字

责任链模式

核心思想

责任链模式允许将请求沿着一条链进行传递,直到有一个对象处理它为止。

典型用例

审批流程

在审批业务流程中,每个审批者可以决定批准、拒绝或将审批传递给更高级别的管理者。

在这个例子中,每个处理者都有自己的处理逻辑和批准权限。请求在责任链上逐级传递,直到找到合适的处理者。通过这种方式,可以灵活地增加、移除或重新排列处理者,而无需修改主要的业务逻辑。这样的设计使得审批流程更加灵活和可扩展。

// npm run code src/code/design-pattern/chain-of-responsibility/approval-process.ts

export {};

// 定义处理者接口,声明处理请求的方法
interface Handler {
    setNext(handler: Handler): Handler;
    handle(request: MyRequest): void;
}

class MyRequest {
    constructor(public type: string, public amount: number) {}
}

// 创建具体处理者,每个处理者决定是否处理请求或将其传递给下一个处理者
class AbstractHandler implements Handler {
    private nextHandler!: Handler;

    public setNext(handler: Handler): Handler {
        this.nextHandler = handler;
        return handler;
    }

    public handle(request: MyRequest): void {
        if (this.nextHandler) {
            this.nextHandler.handle(request);
        }
    }
}

class Manager extends AbstractHandler {
    public handle(request: MyRequest): void {
        if (request.type === 'Leave' && request.amount <= 10) {
            console.log(`Manager will approve ${request.amount} day(s) leave`);
        } else {
            super.handle(request);
        }
    }
}

class Director extends AbstractHandler {
    public handle(request: MyRequest): void {
        if (request.type === 'Leave' && request.amount <= 20) {
            console.log(`Director will approve ${request.amount} day(s) leave`);
        } else {
            super.handle(request);
        }
    }
}

class CEO extends AbstractHandler {
    public handle(request: MyRequest): void {
        // CEO can approve any amount of leave
        console.log(`CEO will approve ${request.amount} day(s) leave`);
    }
}

const manager = new Manager();
const director = new Director();
const ceo = new CEO();

manager.setNext(director).setNext(ceo);

const request = new MyRequest('Leave', 15);
manager.handle(request); // 输出: Director will approve 15 day(s) leave

事件处理系统

在图形用户界面或游戏编程中,责任链模式常用于事件处理,例如:鼠标点击或键盘事件。

// npm run code src/code/design-pattern/chain-of-responsibility/event-processing-system.ts

export {};

// 定义一个事件类
class Event {
    constructor(public type: string) {}
  }
  
  // 定义一个抽象处理者类
  abstract class Handler {
    protected successor: Handler | null = null;
  
    setSuccessor(successor: Handler) {
      this.successor = successor;
    }
  
    abstract handleEvent(event: Event): void;
  }
  
  // 具体的事件处理者类
  class MouseClickHandler extends Handler {
    handleEvent(event: Event) {
      if (event.type === 'mouseClick') {
        console.log('处理鼠标点击事件');
      } else if (this.successor) {
        this.successor.handleEvent(event);
      }
    }
  }
  
  class KeyPressHandler extends Handler {
    handleEvent(event: Event) {
      if (event.type === 'keyPress') {
        console.log('处理键盘按键事件');
      } else if (this.successor) {
        this.successor.handleEvent(event);
      }
    }
  }
  
  class TouchHandler extends Handler {
    handleEvent(event: Event) {
      if (event.type === 'touch') {
        console.log('处理触摸事件');
      } else if (this.successor) {
        this.successor.handleEvent(event);
      }
    }
  }
  
  // 创建事件处理链
  const mouseClickHandler = new MouseClickHandler();
  const keyPressHandler = new KeyPressHandler();
  const touchHandler = new TouchHandler();
  
  mouseClickHandler.setSuccessor(keyPressHandler);
  keyPressHandler.setSuccessor(touchHandler);
  
  // 模拟事件触发
  const clickEvent = new Event('mouseClick');
  const keyEvent = new Event('keyPress');
  const touchEvent = new Event('touch');
  
  mouseClickHandler.handleEvent(clickEvent);
  mouseClickHandler.handleEvent(keyEvent);
  mouseClickHandler.handleEvent(touchEvent);
  

日志记录

在日志记录系统中,可以根据日志的严重级别,将日志传递给不同的处理者。

// npm run code src/code/design-pattern/chain-of-responsibility/log-recording.ts

export {};

// 定义一个日志消息类
class LogMessage {
    constructor(public level: string, public message: string) {}
  }
  
  // 定义一个抽象日志处理者类
  abstract class LogHandler {
    protected nextHandler: LogHandler | null = null;
  
    setNextHandler(handler: LogHandler) {
      this.nextHandler = handler;
    }
  
    abstract handleLogMessage(message: LogMessage): void;
  }
  
  // 具体的日志处理者类
  class ConsoleLogHandler extends LogHandler {
    handleLogMessage(message: LogMessage) {
      if (message.level === 'DEBUG' || message.level === 'INFO') {
        console.log(`[Console] ${message.level}: ${message.message}`);
      }
  
      if (this.nextHandler) {
        this.nextHandler.handleLogMessage(message);
      }
    }
  }
  
  class FileLogHandler extends LogHandler {
    handleLogMessage(message: LogMessage) {
      if (message.level === 'DEBUG' || message.level === 'INFO' || message.level === 'ERROR') {
        // 省略将日志写入文件的代码
        console.log(`[File] ${message.level}: ${message.message}`);
      }
  
      if (this.nextHandler) {
        this.nextHandler.handleLogMessage(message);
      }
    }
  }
  
  class RemoteLogHandler extends LogHandler {
    handleLogMessage(message: LogMessage) {
      // 姑且假设远程服务器可以处理所有级别的日志
      // 省略将日志发送到远程服务器的代码
      console.log(`[Remote] ${message.level}: ${message.message}`);
  
      if (this.nextHandler) {
        this.nextHandler.handleLogMessage(message);
      }
    }
  }
  
  // 创建日志处理链
  const consoleLogHandler = new ConsoleLogHandler();
  const fileLogHandler = new FileLogHandler();
  const remoteLogHandler = new RemoteLogHandler();
  
  consoleLogHandler.setNextHandler(fileLogHandler);
  fileLogHandler.setNextHandler(remoteLogHandler);
  
  // 模拟记录不同级别的日志消息
  const debugMessage = new LogMessage('DEBUG', 'This is a debug message');
  const infoMessage = new LogMessage('INFO', 'This is an info message');
  const errorMessage = new LogMessage('ERROR', 'This is an error message');
  
  consoleLogHandler.handleLogMessage(debugMessage);
  consoleLogHandler.handleLogMessage(infoMessage);
  consoleLogHandler.handleLogMessage(errorMessage);
  

处理网络请求

在使用责任链模式处理网络请求时,会定义一个处理请求的接口,为每个处理阶段(如认证、缓存、数据处理)创建实现这个接口的类。每个处理者会决定是否要处理请求或将其传递给链上的下一个处理者。

// npm run code src/code/design-pattern/chain-of-responsibility/processing-network-requests.ts

export {};

// 请求接口定义
interface MyRequest {
    // 可以定义多种属性,如用户信息、请求数据等
    user: string;
    data: any;
  }
  
  // 处理者接口
  interface Handler {
    setNext(handler: Handler): Handler;
    handle(request: MyRequest): void;
  }
  
  // 抽象处理者
  abstract class AbstractHandler implements Handler {
    private nextHandler!: Handler;
  
    public setNext(handler: Handler): Handler {
      this.nextHandler = handler;
      return handler;
    }
  
    public handle(request: MyRequest): void {
      if (this.nextHandler) {
        this.nextHandler.handle(request);
      }
    }
  }
  
  // 具体处理者:认证
  class AuthenticationHandler extends AbstractHandler {
    public handle(request: MyRequest): void {
      if (this.authenticate(request)) {
        console.log('Authentication successful');
        super.handle(request);
      } else {
        console.log('Authentication failed');
      }
    }
  
    private authenticate(request: MyRequest): boolean {
      // 认证逻辑
      return request.user === "authorized_user";
    }
  }
  
  // 具体处理者:缓存
  class CacheHandler extends AbstractHandler {
    public handle(request: MyRequest): void {
      if (this.isCached(request)) {
        console.log('Returned from cache');
      } else {
        console.log('Not in cache, processing further');
        super.handle(request);
      }
    }
  
    private isCached(request: MyRequest): boolean {
      // 缓存检查逻辑
      return false;
    }
  }
  
  // 具体处理者:数据处理
  class DataHandler extends AbstractHandler {
    public handle(request: MyRequest): void {
      console.log('Processing data');
      super.handle(request);
    }
  }
  
  // 使用责任链
  let request: MyRequest = { user: "authorized_user", data: {} };
  
  let auth = new AuthenticationHandler();
  let cache = new CacheHandler();
  let data = new DataHandler();
  
  auth.setNext(cache).setNext(data);
  
  // 开始处理请求
  auth.handle(request);  

处理命令对象

责任链模式可以让命令对象在一系列处理者之间传递,每个处理者都会检查命令是否为其可以处理的类型,如果是,则处理该命令;如果不是,则将命令传递给链中的下一个处理者。

// npm run code src/code/design-pattern/chain-of-responsibility/process-command-object.ts

export {};

// 命令接口
interface Command {
    execute(): void;
  }
  
  // 具体命令:打开命令
  class OpenCommand implements Command {
    execute(): void {
      console.log("Open command executed");
    }
  }
  
  // 具体命令:关闭命令
  class CloseCommand implements Command {
    execute(): void {
      console.log("Close command executed");
    }
  }
  
  // 处理者接口
  interface Handler {
    setNext(handler: Handler): Handler;
    handle(command: Command): void;
  }
  
  // 抽象处理者
  abstract class AbstractHandler implements Handler {
    private nextHandler!: Handler;
  
    public setNext(handler: Handler): Handler {
      this.nextHandler = handler;
      return handler;
    }
  
    public handle(command: Command): void {
      if (this.nextHandler) {
        this.nextHandler.handle(command);
      }
    }
  }
  
  // 具体处理者:处理打开命令
  class OpenCommandHandler extends AbstractHandler {
    public handle(command: Command): void {
      if (command instanceof OpenCommand) {
        command.execute();
      } else {
        super.handle(command);
      }
    }
  }
  
  // 具体处理者:处理关闭命令
  class CloseCommandHandler extends AbstractHandler {
    public handle(command: Command): void {
      if (command instanceof CloseCommand) {
        command.execute();
      } else {
        super.handle(command);
      }
    }
  }
  
  // 使用责任链
  let openCommand = new OpenCommand();
  let closeCommand = new CloseCommand();
  
  let openHandler = new OpenCommandHandler();
  let closeHandler = new CloseCommandHandler();
  
  openHandler.setNext(closeHandler);
  
  // 处理命令
  openHandler.handle(openCommand);
  openHandler.handle(closeCommand);
  

数据处理管道

责任链模式可以创建一系列处理者,每个处理者负责数据流的一个特定阶段,如过滤、转换或验证。在这种模式下,数据被传递给第一个处理者,然后依次流经各个处理者,每个处理者对数据进行操作,然后将其传递给下一个处理者。

// npm run code src/code/design-pattern/chain-of-responsibility/data-processing-pipeline.ts

export {};

// 数据接口定义
interface Data {
    // 可以定义多种属性,根据实际需求
    value: any;
  }
  
  // 处理器接口
  interface Handler {
    setNext(handler: Handler): Handler;
    handle(data: Data): Data;
  }
  
  // 抽象处理器
  abstract class AbstractHandler implements Handler {
    private nextHandler!: Handler;
  
    public setNext(handler: Handler): Handler {
      this.nextHandler = handler;
      return handler;
    }
  
    public handle(data: Data): Data {
      if (this.nextHandler) {
        return this.nextHandler.handle(data);
      }
      return data;
    }
  }
  
  // 具体处理器:过滤
  class FilterHandler extends AbstractHandler {
    public handle(data: Data): Data {
      // 过滤逻辑
      console.log('Filtering data');
      data.value = data.value.filter((x: any) => x % 2 === 0); // 举例:过滤奇数
      return super.handle(data);
    }
  }
  
  // 具体处理器:转换
  class TransformHandler extends AbstractHandler {
    public handle(data: Data): Data {
      // 转换逻辑
      console.log('Transforming data');
      data.value = data.value.map((x: any) => x * 2); // 举例:每个元素乘以2
      return super.handle(data);
    }
  }
  
  // 具体处理器:验证
  class ValidateHandler extends AbstractHandler {
    public handle(data: Data): Data {
      // 验证逻辑
      console.log('Validating data');
      // 举例:验证操作,这里简单通过所有数据
      return super.handle(data);
    }
  }
  
  // 使用责任链处理数据
  let rawData: Data = { value: [1, 2, 3, 4, 5] };
  
  let filter = new FilterHandler();
  let transform = new TransformHandler();
  let validate = new ValidateHandler();
  
  filter.setNext(transform).setNext(validate);
  
  // 处理数据
  let processedData = filter.handle(rawData);
  console.log('Processed Data:', processedData);
  

上次编辑于: