19. 职责链模式(Chain of Responsibility)

问题:请求需要经过多个处理者,但不想让发送者知道谁会处理。

核心:处理者串成链,每个处理者决定自己处理还是传给下一个。

class Handler {
  #next;
  setNext(h) { this.#next = h; return h; }
  handle(request) {
    if (this.#next) return this.#next.handle(request);
    return null;
  }
}

class AuthHandler extends Handler {
  handle(request) {
    if (!request.token) return '未认证';
    return super.handle(request);
  }
}

class RoleHandler extends Handler {
  handle(request) {
    if (request.role !== 'admin') return '权限不足';
    return super.handle(request);
  }
}

class LogHandler extends Handler {
  handle(request) {
    console.log(`管理员 ${request.user} 操作已记录`);
    return super.handle(request);
  }
}

const auth = new AuthHandler();
auth.setNext(new RoleHandler()).setNext(new LogHandler());

const result = auth.handle({ token: 'abc', role: 'admin', user: '小明' });
// 管理员 小明 操作已记录
console.log(result); // null(全部通过)
package chain

import "fmt"

type Handler interface {
  SetNext(Handler) Handler
  Handle(request map[string]any) string
}

type BaseHandler struct{ next Handler }

func (h *BaseHandler) SetNext(next Handler) Handler {
  h.next = next
  return next
}

func (h *BaseHandler) Handle(request map[string]any) string {
  if h.next != nil {
    return h.next.Handle(request)
  }
  return ""
}

type AuthHandler struct{ BaseHandler }

func (h *AuthHandler) Handle(req map[string]any) string {
  if _, ok := req["token"]; !ok {
    return "未认证"
  }
  return h.BaseHandler.Handle(req)
}

type RoleHandler struct{ BaseHandler }

func (h *RoleHandler) Handle(req map[string]any) string {
  if role, _ := req["role"].(string); role != "admin" {
    return "权限不足"
  }
  return h.BaseHandler.Handle(req)
}

type LogHandler struct{ BaseHandler }

func (h *LogHandler) Handle(req map[string]any) string {
  user, _ := req["user"].(string)
  fmt.Printf("管理员 %s 操作已记录\n", user)
  return h.BaseHandler.Handle(req)
}

Express/Koa 的中间件机制就是这个模式。