抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,用于提供一个接口来创建一系列相关对象。本文以工作流系统中的一个简单流程(用户登录 → 判断是否新用户 → 发送欢迎邮件)为例,基于提供的 NodeType
枚举,展示客户端通过 JSON 数组配置流程,工作流引擎作为抽象工厂提供统一接口创建节点,体现隔离性、一致性和可扩展性。
设计模式原理
抽象工厂模式通过统一的接口创建一组相关对象(如工作流节点),客户端通过 JSON 配置动态定义流程,工厂根据节点类型和参数创建节点,确保隔离性和一致性,同时支持扩展新节点类型。
抽象工厂模式的结构
- AbstractFactory(抽象工厂接口) :声明创建节点的方法。
- ConcreteFactory(具体工厂类) :实现抽象工厂接口,根据 JSON 配置创建节点。
- AbstractProduct(抽象产品接口) :定义节点接口。
- ConcreteProduct(具体产品类) :实现具体节点逻辑。
- Client(客户端) :提供 JSON 数组配置,使用工厂接口创建节点。
优点
- 隔离性:客户端通过 JSON 和工厂接口创建节点,无需知道具体实现。
- 一致性:确保节点基于同一工作流类型,参数一致传递。
- 可扩展性:易于支持新节点类型,只需扩展工厂逻辑。
TypeScript 实现示例
以下示例实现一个工作流:用户登录(TRIGGER
)→ 判断是否新用户(CONDITION
)→ 发送欢迎邮件(ACTION
)。客户端提供 JSON 数组定义流程,工作流引擎作为抽象工厂根据节点类型和参数创建节点。
typescript
// 节点类型枚举
enum NodeType {
TRIGGER = 'trigger',
ACTION = 'action',
CONDITION = 'condition',
LOOP = 'loop',
DELAY = 'delay',
FUNCTION = 'function',
END = 'end',
AGENT = 'agent',
TOOL = 'tool',
MEMORY = 'memory',
PROMPT = 'prompt',
LLM_CALL = 'llm_call',
DATA_TRANSFORM = 'data_transform',
ERROR_HANDLER = 'error_handler'
}
// JSON 节点配置接口
interface NodeConfigJson {
type: NodeType;
params: {
id: string;
[key: string]: any;
};
}
// 抽象产品接口:工作流节点
interface WorkflowNode {
execute(): string;
getDetails(): string;
}
// 具体产品:触发器节点
class TriggerNode implements WorkflowNode {
constructor(private id: string, private params: any) {}
execute(): string {
return `触发器节点(ID: ${this.id}):触发事件 ${this.params.event || '未知事件'}!`;
}
getDetails(): string {
return `详情:触发器节点,ID=${this.id},参数=${JSON.stringify(this.params)}`;
}
}
// 具体产品:条件节点
class ConditionNode implements WorkflowNode {
constructor(private id: string, private params: any) {}
execute(): string {
return `条件节点(ID: ${this.id}):评估条件 ${this.params.condition || '未知条件'}!`;
}
getDetails(): string {
return `详情:条件节点,ID=${this.id},参数=${JSON.stringify(this.params)}`;
}
}
// 具体产品:动作节点
class ActionNode implements WorkflowNode {
constructor(private id: string, private params: any) {}
execute(): string {
return `动作节点(ID: ${this.id}):执行操作 ${this.params.operation || '未知操作'}!`;
}
getDetails(): string {
return `详情:动作节点,ID=${this.id},参数=${JSON.stringify(this.params)}`;
}
}
// 抽象工厂接口
interface WorkflowEngine {
createNode(json: NodeConfigJson): WorkflowNode;
}
// 具体工厂:工作流引擎
class WorkflowEngineFactory implements WorkflowEngine {
private nodeMap: { [key in NodeType]?: new (id: string, params: any) => WorkflowNode } = {
[NodeType.TRIGGER]: TriggerNode,
[NodeType.CONDITION]: ConditionNode,
[NodeType.ACTION]: ActionNode
};
createNode(json: NodeConfigJson): WorkflowNode {
const NodeClass = this.nodeMap[json.type];
if (!NodeClass) throw new Error(`不支持的节点类型:${json.type}`);
return new NodeClass(json.params.id, json.params);
}
}
// 客户端代码:处理 JSON 节点数组
function processWorkflow(engine: WorkflowEngine, nodes: NodeConfigJson[]) {
nodes.forEach((nodeConfig, index) => {
console.log(`处理节点 ${index + 1}(类型:${nodeConfig.type}):`);
const node = engine.createNode(nodeConfig);
console.log(`节点执行:${node.execute()}`);
console.log(`节点详情:${node.getDetails()}`);
console.log("");
});
}
// 测试代码
function main() {
// JSON 配置:用户登录 → 判断是否新用户 → 发送欢迎邮件
const workflowNodes: NodeConfigJson[] = [
{
type: NodeType.TRIGGER,
params: { id: "TRG001", event: "用户登录" }
},
{
type: NodeType.CONDITION,
params: { id: "COND001", condition: "是否新用户" }
},
{
type: NodeType.ACTION,
params: { id: "ACT001", operation: "发送欢迎邮件" }
}
];
console.log("工作流:用户登录 → 判断是否新用户 → 发送欢迎邮件");
const engine = new WorkflowEngineFactory();
processWorkflow(engine, workflowNodes);
}
main();
运行结果
ini
工作流:用户登录 → 判断是否新用户 → 发送欢迎邮件
处理节点 1(类型:trigger):
节点执行:触发器节点(ID: TRG001):触发事件 用户登录!
节点详情:详情:触发器节点,ID=TRG001,参数={"id":"TRG001","event":"用户登录"}
处理节点 2(类型:condition):
节点执行:条件节点(ID: COND001):评估条件 是否新用户!
节点详情:详情:条件节点,ID=COND001,参数={"id":"COND001","condition":"是否新用户"}
处理节点 3(类型:action):
节点执行:动作节点(ID: ACT001):执行操作 发送欢迎邮件!
节点详情:详情:动作节点,ID=ACT001,参数={"id":"ACT001","operation":"发送欢迎邮件"}
总结
通过用户登录工作流的 JSON 配置示例,抽象工厂模式展示了其核心优势:客户端通过 JSON 隔离具体实现,确保节点一致性,并支持扩展新节点类型。在工作流系统中,此模式适合处理动态配置的节点创建,提升代码可维护性和灵活性。