责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,允许将请求沿处理者链传递,直到某个处理者处理请求或链结束为止。
设计模式原理
责任链模式通过构建一个处理者链,允许请求在链中传递,每个处理者决定是否处理请求或传递给下一个处理者。在工作流引擎中,责任链模式适合处理需要多级审批或条件判断的场景(如审批金额、验证权限),通过泛型节点确保类型安全,动态构建处理链。
责任链模式的结构
- Handler(处理者接口) :定义处理请求的方法和设置下一个处理者的方法。
- ConcreteHandler(具体处理者) :实现处理逻辑,决定是否处理或传递请求。
- Client(客户端) :通过 JSON 配置创建处理链并发起请求。
优点
- 解耦性:请求发送者与处理者解耦,客户端无需知道具体处理者。
- 灵活性:动态调整处理链顺序或添加新处理者。
- 类型安全:结合泛型节点,确保请求和处理逻辑的参数类型匹配。
- 可扩展性:新增处理者只需实现新节点,无需修改现有代码。
适用场景
- 需要多级处理请求(如工作流中的审批、验证、日志记录)。
- 处理者顺序或逻辑动态变化。
- 希望通过声明式配置(如 JSON)定义处理链。
TypeScript 实现示例
以下示例在工作流引擎中使用泛型节点 GenericNode<T>
,通过责任链模式实现审批流程。客户端通过 JSON 配置定义处理链(如初级审批 → 高级审批),每个节点决定是否处理请求或传递给下一个节点。
typescript
// 节点类型枚举
enum NodeType {
APPROVAL = 'approval',
VALIDATION = 'validation',
LOGGING = 'logging'
}
// JSON 节点配置接口
interface NodeConfigJson<T = any> {
type: NodeType;
params: T & { id: string };
}
// 请求参数类型
interface ApprovalRequest {
amount: number;
user: string;
}
// 节点参数类型
interface ApprovalParams { id: string; level: string; threshold: number }
interface ValidationParams { id: string; requiredRole: string }
interface LoggingParams { id: string; logLevel: string }
// 泛型节点接口(处理者接口)
interface WorkflowNode<T> {
type: NodeType;
params: T;
setNext(next: WorkflowNode<any>): void;
handle(request: ApprovalRequest): string;
getDetails(): string;
}
// 泛型节点实现
class GenericNode<T> implements WorkflowNode<T> {
private next: WorkflowNode<any> | null = null;
constructor(public type: NodeType, public params: T) {}
setNext(next: WorkflowNode<any>): void {
this.next = next;
}
handle(request: ApprovalRequest): string {
switch (this.type) {
case NodeType.APPROVAL:
const approvalParams = this.params as ApprovalParams;
if (request.amount <= approvalParams.threshold) {
return `审批节点(ID: ${approvalParams.id}, 级别: ${approvalParams.level}):批准金额 ${request.amount}`;
}
return this.passToNext(request, `审批节点(ID: ${approvalParams.id}):金额 ${request.amount} 超出权限`);
case NodeType.VALIDATION:
const validationParams = this.params as ValidationParams;
if (request.user === validationParams.requiredRole) {
return `验证节点(ID: ${validationParams.id}):用户 ${request.user} 权限验证通过`;
}
return this.passToNext(request, `验证节点(ID: ${validationParams.id}):用户 ${request.user} 权限不足`);
case NodeType.LOGGING:
const loggingParams = this.params as LoggingParams;
const logMessage = `日志节点(ID: ${loggingParams.id}, 级别: ${loggingParams.logLevel}):记录请求 ${JSON.stringify(request)}`;
return this.next ? `${logMessage}\n${this.next.handle(request)}` : logMessage;
default:
return `未知节点类型:${this.type}`;
}
}
private passToNext(request: ApprovalRequest, message: string): string {
if (this.next) {
return `${message}\n${this.next.handle(request)}`;
}
return `${message}\n未处理:无后续节点`;
}
getDetails(): string {
return `详情:${this.type} 节点,ID=${this.params.id}, 参数=${JSON.stringify(this.params)}`;
}
}
// 工厂类:创建节点
class WorkflowNodeFactory {
createNode<T>(config: NodeConfigJson<T>): WorkflowNode<T> {
return new GenericNode<T>(config.type, config.params);
}
}
// 客户端代码:构建处理链并处理请求
function processWorkflow(factory: WorkflowNodeFactory, nodes: NodeConfigJson[], request: ApprovalRequest) {
const workflowNodes = nodes.map(config => factory.createNode(config));
// 构建责任链
for (let i = 0; i < workflowNodes.length - 1; i++) {
workflowNodes[i].setNext(workflowNodes[i + 1]);
}
// 输出节点详情
console.log("=== 责任链详情 ===");
workflowNodes.forEach((node, index) => {
console.log(`节点 ${index + 1} 详情:${node.getDetails()}`);
});
// 处理请求
console.log("\n=== 处理请求 ===");
const result = workflowNodes[0].handle(request);
console.log(result);
}
// 测试代码
function main() {
// JSON 配置:初级审批 → 高级审批 → 日志记录
const workflowNodes: NodeConfigJson[] = [
{
type: NodeType.APPROVAL,
params: { id: "APP001", level: "初级", threshold: 1000 }
},
{
type: NodeType.APPROVAL,
params: { id: "APP002", level: "高级", threshold: 5000 }
},
{
type: NodeType.LOGGING,
params: { id: "LOG001", logLevel: "INFO" }
}
];
// 测试请求
const request1: ApprovalRequest = { amount: 800, user: "manager" };
const request2: ApprovalRequest = { amount: 2000, user: "manager" };
console.log("工作流:初级审批 → 高级审批 → 日志记录");
const factory = new WorkflowNodeFactory();
console.log("\n=== 测试请求1(金额800) ===");
processWorkflow(factory, workflowNodes, request1);
console.log("\n=== 测试请求2(金额2000) ===");
processWorkflow(factory, workflowNodes, request2);
}
main();
运行结果
ini
工作流:初级审批 → 高级审批 → 日志记录
=== 测试请求1(金额800) ===
=== 责任链详情 ===
节点 1 详情:详情:approval 节点,ID=APP001, 参数={"id":"APP001","level":"初级","threshold":1000}
节点 2 详情:详情:approval 节点,ID=APP002, 参数={"id":"APP002","level":"高级","threshold":5000}
节点 3 详情:详情:logging 节点,ID=LOG001, 参数={"id":"LOG001","logLevel":"INFO"}
=== 处理请求 ===
审批节点(ID: APP001, 级别: 初级):批准金额 800
日志节点(ID: LOG001, 级别: INFO):记录请求 {"amount":800,"user":"manager"}
=== 测试请求2(金额2000) ===
=== 责任链详情 ===
节点 1 详情:详情:approval 节点,ID=APP001, 参数={"id":"APP001","level":"初级","threshold":1000}
节点 2 详情:详情:approval 节点,ID=APP002, 参数={"id":"APP002","level":"高级","threshold":5000}
节点 3 详情:详情:logging 节点,ID=LOG001, 参数={"id":"LOG001","logLevel":"INFO"}
=== 处理请求 ===
审批节点(ID: APP001):金额 2000 超出权限
审批节点(ID: APP002, 级别: 高级):批准金额 2000
日志节点(ID: LOG001, 级别: INFO):记录请求 {"amount":2000,"user":"manager"}
总结
通过泛型节点 GenericNode<T>
,责任链模式在工作流引擎中实现了请求的动态处理。客户端通过 JSON 配置定义处理链,节点根据条件处理请求或传递给下一个节点。泛型确保了类型安全,责任链模式提供了解耦性和灵活性,适合处理多级审批或验证的工作流场景。