Easy-Flows - Java的简单愚蠢的工作流引擎

序言

Easy Flows 是一个专为Java设计的轻量级工作流引擎,它提供简洁的API和构建块,使得创建和运行可组合的工作流程变得简单易行。无需复杂的概念或专用语言,只需熟悉自然的编程接口,即可轻松上手。

什么是容易流?

轻松流是Java的工作流引擎。 它提供简单的api和构建块,以方便创建和运行可以组合工作流。

简单流程中的工作单元由 Work 接口表示。 工作流由 WorkFlow 接口表示。 轻松流提供 WorkFlow 接口的4实现: easy-flows介绍 这些是你需要知道的唯一基本流,以便开始创建简单流程的工作流。 你不需要学习复杂的符号或者概念,只是一些简单易于思考的自然 api。

它是如何工作的?

首先,让我们写一些Work:

class PrintMessageWork implements Work {
 
    private String message;
 
    public PrintMessageWork(String message) {
        this.message = message;
    }
 
    public String getName() {
        return "print message work";
    }
 
    @Override
    public WorkReport call(WorkContext workContext) {
        System.out.println(message);
        return new DefaultWorkReport(WorkStatus.COMPLETED, workContext);
    }
}

这里工作单元将给定消息打印到标准输出。 现在假设我们想创建以下工作流:

  • 打印"foo"三次
  • 然后并行打印"hello"和"world"
  • 如果"hello"和"world"都已经成功打印到控制台,则打印"ok",否则打印"nok"

这里工作流可以如下所示: easy-flows介绍

  • flow1 是 work1的 RepeatFlow,它打印"foo"三次
  • flow2 是 work2 和 work3 的ParallelFlow,它并行地打印"hello"和"world"
  • flow3 是一个 ConditionalFlow,它先执行 flow2 ( 工作流也是工作),如果 - - flow2 完成,则执行 work4,否则将分别打印“ok”和“nok”。
  • flow4 是一个 SequentialFlow 它执行 flow1,然后按顺序执行 flow3。

通过轻松流,可以使用以下代码段实现这里工作流:

PrintMessageWork work1 = new PrintMessageWork("foo");
PrintMessageWork work2 = new PrintMessageWork("hello");
PrintMessageWork work3 = new PrintMessageWork("world");
PrintMessageWork work4 = new PrintMessageWork("ok");
PrintMessageWork work5 = new PrintMessageWork("nok");
 
ExecutorService executorService = Executors.newFixedThreadPool(2);
WorkFlow workflow = aNewSequentialFlow() // flow 4
        .execute(aNewRepeatFlow() // flow 1
                    .named("print foo 3 times")
                    .repeat(work1)
                    .times(3)
                    .build())
        .then(aNewConditionalFlow() // flow 3
                .execute(aNewParallelFlow(executorService) // flow 2
                            .named("print 'hello' and 'world' in parallel")
                            .execute(work2, work3)
                            .build())
                .when(WorkReportPredicate.COMPLETED)
                .then(work4)
                .otherwise(work5)
                .build())
        .build();
 
WorkFlowEngine workFlowEngine = aNewWorkFlowEngine().build();
WorkContext workContext = new WorkContext();
WorkReport workReport = workFlowEngine.run(workflow, workContext);
executorService.shutdown();

详细使用

除了上述介绍的流操作,还可以参考下面具体的详细用例,涉及如何传入context,如何执行工作流等

package org.example.workflow.test;

import org.example.workflow.work.PrintMessageWork;
import org.jeasy.flows.work.WorkContext;
import org.jeasy.flows.work.WorkReport;
import org.jeasy.flows.work.WorkReportPredicate;
import org.jeasy.flows.workflow.ConditionalFlow;
import org.jeasy.flows.workflow.ParallelFlow;
import org.jeasy.flows.workflow.RepeatFlow;
import org.jeasy.flows.workflow.SequentialFlow;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestWorkFlowSimple {

    public static void main(String[] args) {
        //init
        PrintMessageWork work1 = new PrintMessageWork("flow");
        PrintMessageWork work2 = new PrintMessageWork("hello");
        PrintMessageWork work3 = new PrintMessageWork("world");
        PrintMessageWork work4 = new PrintMessageWork("ok");
        PrintMessageWork work5 = new PrintMessageWork("nok");

        ExecutorService executorService = Executors.newFixedThreadPool(2);
        RepeatFlow repeatFlow = RepeatFlow.Builder.aNewRepeatFlow()
                .named("repeatFlow")
                .repeat(work1)
                .times(3)
                .build();
        ParallelFlow parallelFlow = ParallelFlow.Builder.aNewParallelFlow()
                .named("parallelFlow")
                .execute(work2, work3)
                .with(executorService)
                .build();
        ConditionalFlow conditionalFlow = ConditionalFlow.Builder.aNewConditionalFlow()
                .named("conditionalFlow")
                .execute(parallelFlow)
                .when(WorkReportPredicate.COMPLETED)
                .then(work4)
                .otherwise(work5)
                .build();
        SequentialFlow sequentialFlow = SequentialFlow.Builder.aNewSequentialFlow()
                .execute(repeatFlow)
                .then(conditionalFlow)
                .build();
        WorkContext workContext = new WorkContext();
        workContext.put("linyi", "1234567890");
        WorkReport workReport = sequentialFlow.execute(workContext);
        System.out.println(workReport);
        executorService.shutdown();
    }

}

总结

Easy Flows适合那些需要处理流程控制但又不想被复杂的业务流程管理工具束缚的应用。它可以用于:

  • 多步服务操作:比如订单处理、用户注册等需要按照特定顺序进行的业务逻辑。
  • 异步任务调度:并行处理多个任务,如数据抓取、文件处理等。
  • 决策分支:基于某些条件选择不同的执行路径,如异常处理、权限验证等。
end

评论