java工作流模式、背包模式、适配器工厂模式整合架构,让服务任务编排更便捷

工作流和背包模式虽然不在23种常用设计模式中,但是在对任务编排处理类的业务代码使用起来是非常有用的。

下面给大家介绍下工作流模式:

例如,我之前有个项目需要对模型进行转换,因为不同配置的模型需要使用的转换方法不同,且单个模型需要经历多次的执行转换脚本,那就可以把每个脚本抽离出来封装为工作流中的一个字节点,通过对节点编排适应不同的转换任务,代码流程清晰,转换流程通过配置文件进行配置。

背包模式呢,其实并不算是一种标准的设计模式,逻辑上可以理解为借鉴现实中"背包"的特性:可以装载不同类型的物品,并方便地进行取出或使用。在软件开发中,配合工作流模式,可以非常方便为工作流节点的执行提供需要的参数,这个也是我在非23种常用设计模式外比较喜欢的一种模式,例如在执行某个任务需要大量的组装参数等模式的代码上,我比较喜欢封装到统一的一个类中处理,后续的任务就把这个类从上至下传递,所有需要的参数都从类中直接获取,不需要在业务代码用到的地方才再去处理参数,而是预处理好参数,需要就去取。相当于把后续处理的多数参数都揣到兜里,需要就掏出来。

给大家一个简单的 工作流、背包、工厂、适配器模式的整合demo:

适配器模式的核心目的是将一个接口转换为客户期望的另一个接口,从而兼容不同接口的实现。这在代码中也有所体现:

工厂模式职责:

• WorkflowNodeFactory 提供了一个中央注册表,用于将 type 和实际适配器类(Class)关联起来。

• 工厂方法 createNode 根据类型创建实例并注入配置。

• 工厂屏蔽了对象创建的细节,外部调用者不需要知道具体的适配器实现类。

适配器职责:PaymentServiceAdapter、MessageQueueAdapter 和 CustomLoggingAdapter 都实现了统一的接口 WorkflowAdapter,屏蔽了每个模块的差异。

• 比如,PaymentServiceAdapter 适配了支付模块的内部逻辑。

• MessageQueueAdapter 适配了消息队列的逻辑。

统一接口

• 这些适配器共同实现 WorkflowAdapter 接口,工作流引擎调用时无需关心具体的适配器实现,只需要依赖接口即可。

• 每个适配器从外部来看都实现了统一的 execute 方法,但内部适配了不同的逻辑和数据。

项目结构:

src/

├── adapters/

│ ├── WorkflowAdapter.java

│ ├── ConfigurableAdapter.java

│ ├── PaymentServiceAdapter.java

│ ├── MessageQueueAdapter.java

│ ├── CustomLoggingAdapter.java

├── core/

│ ├── WorkflowNodeFactory.java

│ ├── WorkflowConfigLoader.java

│ ├── ConfigurableWorkflow.java

│ ├── Backpack.java

├── main/

│ ├── WorkflowTest.java

resources/

├── workflow-config.yaml

1.WorkflowAdapter 接口 (工作流子节点实现的接口类):

java 复制代码
package adapters;

import core.Backpack;

public interface WorkflowAdapter {
    void execute(Backpack context);
}

2. ConfigurableAdapter 接口

java 复制代码
package adapters;

import java.util.Map;

public interface ConfigurableAdapter {
    void setConfig(Map<String, Object> config);
}

3. PaymentServiceAdapter 测试子节点1

java 复制代码
package adapters;

import core.Backpack;
import java.util.Map;

public class PaymentServiceAdapter implements WorkflowAdapter, ConfigurableAdapter {
    private String orderIdKey;
    private String amountKey;

    @Override
    public void setConfig(Map<String, Object> config) {
        this.orderIdKey = (String) config.get("orderIdKey");
        this.amountKey = (String) config.get("amountKey");
    }

    @Override
    public void execute(Backpack context) {
        System.out.println("Executing Payment Service...");
        String orderId = context.get(orderIdKey, String.class);
        Double amount = context.get(amountKey, Double.class);

        System.out.println("Processing payment for Order ID: " + orderId + ", Amount: " + amount);
        context.put("paymentSuccess", true);
    }
}

4. MessageQueueAdapter 测试子节点2

java 复制代码
package adapters;

import core.Backpack;
import java.util.Map;

public class MessageQueueAdapter implements WorkflowAdapter, ConfigurableAdapter {
    private String messageKey;

    @Override
    public void setConfig(Map<String, Object> config) {
        this.messageKey = (String) config.get("messageKey");
    }

    @Override
    public void execute(Backpack context) {
        System.out.println("Executing Message Queue Adapter...");
        String message = context.get(messageKey, String.class);

        System.out.println("Sending message to queue: " + message);
        context.put("messageSent", true);
    }
}

5. CustomLoggingAdapter 测试子节点3

java 复制代码
package adapters;

import core.Backpack;
import java.util.Map;

public class CustomLoggingAdapter implements WorkflowAdapter, ConfigurableAdapter {
    private String logMessage;

    @Override
    public void setConfig(Map<String, Object> config) {
        this.logMessage = (String) config.get("logMessage");
    }

    @Override
    public void execute(Backpack context) {
        System.out.println("Executing Custom Logging Adapter...");
        System.out.println(logMessage);
    }
}

6. Backpack 背包模式简单实现类

java 复制代码
package core;

import java.util.HashMap;
import java.util.Map;

public class Backpack {
    private final Map<String, Object> data = new HashMap<>();

    public <T> void put(String key, T value) {
        data.put(key, value);
    }

    public <T> T get(String key, Class<T> type) {
        return type.cast(data.get(key));
    }

    @Override
    public String toString() {
        return "Backpack{" +
                "data=" + data +
                '}';
    }
}

7. WorkflowNodeFactory 初始化工作流子节点工厂类

java 复制代码
package core;

import adapters.WorkflowAdapter;
import adapters.ConfigurableAdapter;
import adapters.PaymentServiceAdapter;
import adapters.MessageQueueAdapter;
import adapters.CustomLoggingAdapter;

import java.util.HashMap;
import java.util.Map;

public class WorkflowNodeFactory {
    private static final Map<String, Class<? extends WorkflowAdapter>> adapterRegistry = new HashMap<>();

    static {
        adapterRegistry.put("PaymentServiceAdapter", PaymentServiceAdapter.class);
        adapterRegistry.put("MessageQueueAdapter", MessageQueueAdapter.class);
        adapterRegistry.put("CustomLoggingAdapter", CustomLoggingAdapter.class);
    }

    public static WorkflowAdapter createNode(String type, Map<String, Object> config) {
        Class<? extends WorkflowAdapter> adapterClass = adapterRegistry.get(type);
        if (adapterClass == null) {
            throw new IllegalArgumentException("Unknown adapter type: " + type);
        }

        try {
            WorkflowAdapter adapter = adapterClass.getDeclaredConstructor().newInstance();

            if (adapter instanceof ConfigurableAdapter) {
                ((ConfigurableAdapter) adapter).setConfig(config);
            }

            return adapter;
        } catch (Exception e) {
            throw new RuntimeException("Failed to create adapter for type: " + type, e);
        }
    }
}

8. WorkflowConfigLoader 工作流加载初始化类

java 复制代码
package core;

import org.yaml.snakeyaml.Yaml;

import java.io.InputStream;
import java.util.List;
import java.util.Map;

public class WorkflowConfigLoader {
    public static List<Map<String, Object>> loadWorkflowConfig(String filePath) {
        Yaml yaml = new Yaml();
        try (InputStream input = WorkflowConfigLoader.class.getResourceAsStream(filePath)) {
            Map<String, Object> config = yaml.load(input);
            return (List<Map<String, Object>>) config.get("workflow");
        } catch (Exception e) {
            throw new RuntimeException("Failed to load workflow configuration", e);
        }
    }
}

9. ConfigurableWorkflow 读取工作流配置类

java 复制代码
package core;

import adapters.WorkflowAdapter;

import java.util.List;
import java.util.Map;

public class ConfigurableWorkflow {
    private List<WorkflowAdapter> nodes;

    public ConfigurableWorkflow(String configFilePath) {
        List<Map<String, Object>> configList = WorkflowConfigLoader.loadWorkflowConfig(configFilePath);

        nodes = configList.stream()
                .map(config -> {
                    String type = (String) config.get("type");
                    Map<String, Object> nodeConfig = (Map<String, Object>) config.get("config");
                    return WorkflowNodeFactory.createNode(type, nodeConfig);
                })
                .toList();
    }

    public void execute(Backpack context) {
        for (WorkflowAdapter node : nodes) {
            node.execute(context);
        }
    }
}

10. WorkflowTest 测试类

java 复制代码
package main;

import core.Backpack;
import core.ConfigurableWorkflow;

public class WorkflowTest {
    public static void main(String[] args) {
        ConfigurableWorkflow workflow = new ConfigurableWorkflow("/workflow-config.yaml");

        Backpack context = new Backpack();
        context.put("orderId", "ORDER123");
        context.put("amount", 199.99);
        context.put("notificationMessage", "Order ORDER123 has been processed!");

        workflow.execute(context);

        System.out.println("Final Context Data: " + context);
    }
}

11. workflow-config.yaml

java 复制代码
workflow:
  - type: PaymentServiceAdapter
    config:
      orderIdKey: "orderId"
      amountKey: "amount"
  - type: MessageQueueAdapter
    config:
      messageKey: "notificationMessage"
  - type: CustomLoggingAdapter
    config:
      logMessage: "Workflow completed successfully."

maven库引入:

java 复制代码
<dependency>
    <groupId>org.yaml</groupId>
    <artifactId>snakeyaml</artifactId>
    <version>2.0</version>
</dependency>
相关推荐
luoganttcc2 小时前
[源码解析] 模型并行分布式训练Megatron (2) --- 整体架构
分布式·架构·大模型
2401_8576100310 小时前
中文学习系统:成本效益分析与系统优化
java·数据库·学习·架构
huaqianzkh10 小时前
数据流图和流程图的区别
架构·流程图
time_silence11 小时前
微服务——数据管理与一致性
微服务·云原生·架构
小小小妮子~14 小时前
深入理解 MySQL 架构
数据库·mysql·架构
雪球不会消失了15 小时前
MVC架构模式
架构·mvc
抓哇FullStack-Junior15 小时前
设计模式——适配器模式
java·设计模式·适配器模式
云云32117 小时前
云手机:Facebook多账号管理的创新解决方案
服务器·线性代数·安全·智能手机·架构·facebook
ThetaarSofVenice17 小时前
带着国标充电器出国怎么办? 适配器模式(Adapter Pattern)
java·适配器模式