当前位置: 首页 > article >正文

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 接口 (工作流子节点实现的接口类):

package adapters;

import core.Backpack;

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

 2. ConfigurableAdapter 接口

package adapters;

import java.util.Map;

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

3. PaymentServiceAdapter  测试子节点1

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

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

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  背包模式简单实现类

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   初始化工作流子节点工厂类 

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    工作流加载初始化类

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    读取工作流配置类

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 测试类

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

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

maven库引入:

<dependency>
    <groupId>org.yaml</groupId>
    <artifactId>snakeyaml</artifactId>
    <version>2.0</version>
</dependency>


http://www.kler.cn/a/460005.html

相关文章:

  • 数据挖掘——聚类
  • Python判别不同平台操作系统调用相应的动态库读写NFC
  • 系统设计——大文件传输方案设计
  • linux文件类型和根目录结构
  • 【网络安全 | 漏洞挖掘】硬编码凭据泄露实现支付系统账户接管
  • 汇编语言:从键盘输入数字字符,(计算阶乘),以无符号十进制形式输出(分支、循环程序)
  • 如何在LabVIEW中更好地使用ActiveX控件?
  • JJJ:linux等待队列用法 init_waitqueue_entry
  • Java虚拟机——JVM高级特性与最佳实践
  • 第10章 初等数论
  • python修改ppt中的文字部分及插入图片
  • 【TG\SE二次开发】天工CAD二次开发-c++模板介绍
  • UniApp 路由导航详解
  • 【数据结构】非线性数据结构——图
  • Oracle复合索引规则指南
  • 大模型Weekly 03|OpenAI o3发布;DeepSeek-V3上线即开源!
  • 【Linux知识】exec命令行详解
  • 关于 覆铜与导线之间间距较小需要增加间距 的解决方法
  • MATLAB语言的计算机基础
  • 自学记录HarmonyOS Next Image API 13:图像处理与传输的开发实践
  • 大数据研究方向有哪些创新点
  • Go中的逃逸分析
  • JS async await fetch 捕获后端500错误详细信息
  • Visual Studio 中增加的AI功能
  • 【文献精读笔记】Explainability for Large Language Models: A Survey (大语言模型的可解释性综述)(一)
  • JS中Symbol (符号)数据类型详解和应用场景