TypeScript设计模式:抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,用于提供一个接口来创建一系列相关对象。本文以工作流系统中的一个简单流程(用户登录 → 判断是否新用户 → 发送欢迎邮件)为例,基于提供的 NodeType 枚举,展示客户端通过 JSON 数组配置流程,工作流引擎作为抽象工厂提供统一接口创建节点,体现隔离性、一致性和可扩展性。

设计模式原理

抽象工厂模式通过统一的接口创建一组相关对象(如工作流节点),客户端通过 JSON 配置动态定义流程,工厂根据节点类型和参数创建节点,确保隔离性和一致性,同时支持扩展新节点类型。

抽象工厂模式的结构

  1. AbstractFactory(抽象工厂接口) :声明创建节点的方法。
  2. ConcreteFactory(具体工厂类) :实现抽象工厂接口,根据 JSON 配置创建节点。
  3. AbstractProduct(抽象产品接口) :定义节点接口。
  4. ConcreteProduct(具体产品类) :实现具体节点逻辑。
  5. 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 隔离具体实现,确保节点一致性,并支持扩展新节点类型。在工作流系统中,此模式适合处理动态配置的节点创建,提升代码可维护性和灵活性。

相关推荐
华仔啊2 小时前
Vue3+CSS 实现的 3D 卡片动画,让你的网页瞬间高大上
前端·css
没逻辑2 小时前
Post-Quantum HTTPS:未来的安全通信架构
后端·安全
江城开朗的豌豆2 小时前
解密React虚拟DOM:我的高效渲染秘诀 🚀
前端·javascript·react.js
云中雾丽2 小时前
Redis 使用记录
后端
vivo互联网技术2 小时前
拥抱新一代 Web 3D 引擎,Three.js 项目快速升级 Galacean 指南
前端·three.js
江城开朗的豌豆2 小时前
React应用优化指南:让我的项目性能“起飞”✨
前端·javascript·react.js
会飞的青蛙2 小时前
GIT 配置别名&脚本自动化执行
前端·git
再吃一根胡萝卜2 小时前
🔍 当 `<a-menu>` 遇上 `<template>`:一个容易忽视的菜单渲染陷阱
前端