Say Goodbye to If‑Else Nightmares with Flow Orchestration
The article explains how excessive if‑else logic in Java back‑ends harms code isolation and scalability, and demonstrates a practical workflow‑orchestration solution using a FlowChain engine, complete with configuration, node definitions, execution flow, and source code examples from the open‑source MemberClub project.
Configure Flow Execution Chain
Different membership product transaction processes require distinct flow chains. The class DemoMemberPurchaseExtension implements a purchase extension point and defines three flow‑chain configurations, as shown in the screenshot.
Define Flow Nodes
Each flow node provides four methods: process, success, rollback, and callback. The diagram illustrates how these methods are declared.
Flow Execution
To run a flow, provide a context object and call FlowChain.execute. The engine links the nodes and executes them sequentially, following a responsibility‑chain pattern.
The execution order is:
Invoke each node's process method in order.
If a process throws an exception, invoke rollback on already‑executed nodes in reverse order.
If all process calls succeed, invoke success on nodes in reverse order.
Finally, call callback on every node regardless of success or failure.
Flow Engine Execution Principle
The core of FlowChain.execute is shown below:
public <T> void execute(FlowChain<T> chain, T context) {
Exception exception = null;
int index = -1;
for (FlowNode<T> node : chain.getNodes()) {
try {
node.process(context);
index++;
} catch (Exception e) {
if (e instanceof SkipException) {
CommonLog.warn("当前流程:{} 发出 Skip请求,后续流程不再执行", node.getClass().getSimpleName());
break;
}
exception = e;
break;
}
}
if (exception != null) {
for (int i = index; i >= 0; i--) {
FlowNode<T> node = chain.getNodes().get(i);
try { node.rollback(context, exception); } catch (Exception e) { CommonLog.error("rollback执行异常,忽略 name:{}", node.getClass().getSimpleName(), e); }
}
} else {
for (int i = index; i >= 0; i--) {
FlowNode<T> node = chain.getNodes().get(i);
try { node.success(context); } catch (Exception e) { CommonLog.error("success 执行异常,忽略 name:{}", node.getClass().getSimpleName(), e); }
}
}
for (int i = index; i >= 0; i--) {
FlowNode<T> node = chain.getNodes().get(i);
try { node.callback(context, exception); } catch (Exception e) { CommonLog.error("callback执行异常,忽略 name:{}", node.getClass().getSimpleName(), e); }
}
if (exception != null) { throw exception; }
}The full source code resides in the MemberClub repository:
https://gitee.com/-/ide/project/juejinwuyang/memberclub/edit/master/-/memberclub.common/src/main/java/com/memberclub/common/flow/FlowChainService.java
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Architect Handbook
Focused on Java interview questions and practical article sharing, covering algorithms, databases, Spring Boot, microservices, high concurrency, JVM, Docker containers, and ELK-related knowledge. Looking forward to progressing together with you.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
