Why Over‑Design Breaks Your Code and How a Flow Engine Restores Simplicity
The article explains how excessive if‑else branching in backend services leads to fragile code, introduces a workflow engine and plugin extension mechanism to isolate business logic, shows concrete configuration and execution steps using the open‑source MemberClub project, and provides the full Java implementation of the FlowChain executor.
As a senior architect, the author argues that a good programmer should avoid over‑design and keep implementations as simple as possible. In a business‑centered architecture, many different partners need slightly different processing, which often results in massive if‑else blocks that are hard to maintain and test.
Problem: Code entanglement and maintenance risk
When ten or more business lines are integrated, each with its own variations, developers end up writing code like:
if (biz == BizA || biz == BizB) {
// common logic
if (biz == BizA) {
// BizA specific handling
}
if (biz == BizB) {
// BizB specific handling
}
}Adding a new business requires inserting more branches, increasing the chance of bugs and making regression testing across all lines unrealistic.
Solution: Workflow engine + plugin extension
Configure a separate flow chain for each business scenario.
Implement business‑specific extensions as plugins that the engine invokes.
The open‑source MemberClub project (hosted on Gitee) demonstrates this approach. It provides a paid‑membership transaction solution and uses the workflow engine to isolate business logic.
Configuring the flow chain
Each membership product defines its own flow chain by implementing an extension point, e.g. DemoMemberPurchaseExtension. The configuration is visualised in the following diagram:
Defining flow nodes
A flow node implements four methods:
process success rollback callbackThe node lifecycle is shown below:
Flow execution
During execution the engine calls FlowChain.execute with a context object. Nodes are processed sequentially; if a node throws an exception, the engine jumps to the rollback phase. If all process calls succeed, the engine runs the success methods in reverse order, followed by callback for each node.
Core implementation of FlowChain.execute
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("Current flow:{} sent Skip request, stop further execution", 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 execution exception, ignore 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 execution exception, ignore 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 execution exception, ignore name:{}", node.getClass().getSimpleName(), e);
}
}
if (exception != null) {
throw exception;
}
}Where to find the full source
The complete code resides in the MemberClub repository:
https://gitee.com/juejinwuyang/memberclub
Specific file:
https://gitee.com/-/ide/project/juejinwuyang/memberclub/edit/master/-/memberclub.common/src/main/java/com/memberclub/common/flow/FlowChainService.java
The project also integrates many useful components (MyBatis‑Plus, ShardingSphere, Redis, Apollo, Spring Cloud, RabbitMQ, Swagger, Lombok, etc.), making it a valuable reference for building robust business‑centered backends.
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.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
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.
