Mastering Complex Business Logic: A Structured Decomposition Methodology
This article presents a practical methodology for handling complex business scenarios by combining top‑down process decomposition with bottom‑up object modeling, emphasizing simple pipelines over heavyweight tools, and demonstrates how to achieve clean, maintainable backend code through real‑world examples and diagrams.
People who know me understand that I have been focusing on application architecture and code complexity governance.
Recently I examined the retail product domain code. Facing the intricate business scenario of Retail Cloud, I explored how to address it at the architecture and code levels, developing a detailed methodology for writing complex business code, which I share here.
I believe this methodology can be applied to most complex business contexts.
A Complex Business Process
Business Background
Retail Cloud supplies offline stores via a B2B model, aiming to digitally reconstruct traditional supply‑chain channels, improve efficiency, and support new retail. Alibaba acts as the platform, providing service functions within the Bsbc framework.
In the product domain, operators perform an "on‑sale" action; after on‑sale, the product becomes available for stores on Retail Cloud.
On‑sale is a critical operation, involving extensive data validation and related actions.
A simplified on‑sale workflow is illustrated below:
Process Decomposition
For such complex business, no one would write everything in a single service method. If one class cannot solve it, we should divide and conquer.
Engineers who adopt divide‑and‑conquer thinking are already ahead of those who don’t. However, many rely excessively on tools or auxiliary mechanisms for decomposition, such as custom workflow engines or database‑driven processes.
These auxiliary mechanisms essentially implement a pipeline, adding unnecessary complexity. I recommend keeping it simple (KISS): ideally avoid tools, at most use a minimal pipeline pattern, and avoid heavyweight workflow engines unless strong visual orchestration is required.
Returning to the on‑sale problem, the core issue is not the tools or design patterns but how to decompose and abstract the problem. Using a structured decomposition, we can break the problem into a hierarchical pyramid.
With this decomposition, the code resembles a book with a clear table of contents.
For on‑sale, the entry point is an OnSaleCommand, composed of three phases.
<ol><li><code>@Command</code></li><li><code>public class OnSaleNormalItemCmdExe {</code></li><li><code>@Resource</code></li><li><code>private OnSaleContextInitPhase onSaleContextInitPhase;</code></li><li><code>@Resource</code></li><li><code>private OnSaleDataCheckPhase onSaleDataCheckPhase;</code></li><li><code>@Resource</code></li><li><code>private OnSaleProcessPhase onSaleProcessPhase;</code></li><li><code>@Override</code></li><li><code>public Response execute(OnSaleNormalItemCmd cmd) {</code></li><li><code>OnSaleContext onSaleContext = init(cmd);</code></li><li><code>checkData(onSaleContext);</code></li><li><code>process(onSaleContext);</code></li><li><code>return Response.buildSuccess();</code></li><li><code>}</code></li><li><code>private OnSaleContext init(OnSaleNormalItemCmd cmd) {</code></li><li><code>return onSaleContextInitPhase.init(cmd);</code></li><li><code>}</code></li><li><code>private void checkData(OnSaleContext onSaleContext) {</code></li><li><code>onSaleDataCheckPhase.check(onSaleContext);</code></li><li><code>}</code></li><li><code>private void process(OnSaleContext onSaleContext) {</code></li><li><code>onSaleProcessPhase.process(onSaleContext);</code></li><li><code>}</code></li></ol>Each phase can be further split into multiple steps. For example, OnSaleProcessPhase consists of several steps:
<ol><li><code>@Phase</code></li><li><code>public class OnSaleProcessPhase {</code></li><li><code>@Resource</code></li><li><code>private PublishOfferStep publishOfferStep;</code></li><li><code>@Resource</code></li><li><code>private BackOfferBindStep backOfferBindStep;</code></li><li><code>// other steps omitted</code></li><li><code>public void process(OnSaleContext onSaleContext) {</code></li><li><code>SupplierItem supplierItem = onSaleContext.getSupplierItem();</code></li><li><code>// generate OfferGroupNo</code></li><li><code>generateOfferGroupNo(supplierItem);</code></li><li><code>// publish offer</code></li><li><code>publishOffer(supplierItem);</code></li><li><code>// bind back‑offer stock</code></li><li><code>bindBackOfferStock(supplierItem);</code></li><li><code>// sync stock route</code></li><li><code>syncStockRoute(supplierItem);</code></li><li><code>// set virtual product extension</code></li><li><code>setVirtualProductExtension(supplierItem);</code></li><li><code>// mark send protection</code></li><li><code>markSendProtection(supplierItem);</code></li><li><code>// record change detail</code></li><li><code>recordChangeDetail(supplierItem);</code></li><li><code>// sync supply price to back‑offer</code></li><li><code>syncSupplyPriceToBackOffer(supplierItem);</code></li><li><code>// set combine product extension</code></li><li><code>setCombineProductExtension(supplierItem);</code></li><li><code>// remove sell‑out tag</code></li><li><code>removeSellOutTag(offerId);</code></li><li><code>// fire domain event</code></li><li><code>fireDomainEvent(supplierItem);</code></li><li><code>// close related issues</code></li><li><code>closeIssues(supplierItem);</code></li><li><code>}</code></li></ol>This illustrates the entire on‑sale business flow. No workflow engine is needed; a simple composed‑method pattern suffices.
When decomposing, engineers should focus less on tools and more on problem analysis, structured decomposition, and proper abstraction into phases and steps.
Two Issues After Decomposition
Although the decomposed code is clearer and more maintainable, two problems remain:
1. Domain knowledge is fragmented. Each use case only handles its own flow, leaving no place to aggregate domain knowledge, leading to duplicated logic across use cases.
2. Business expression capability is missing. Procedural code merely fetches data, performs calculations, and stores data, making it hard to explicitly express business intent without a proper model.
For example, a stock check for combined products originally looks like this:
boolean isCombineProduct = supplierItem.getSign().isCombProductQuote();
if (WarehouseTypeEnum.isAliWarehouse(supplierItem.getWarehouseType())) {
if (CollectionUtil.isEmpty(supplierItem.getWarehouseIdList()) && !isCombineProduct) {
throw ExceptionFactory.makeFault(ServiceExceptionCode.SYSTEM_ERROR, "Cannot publish Offer, contact warehouse operations!");
}
Long sellableAmount = 0L;
if (!isCombineProduct) {
sellableAmount = normalBiz.acquireSellableAmount(supplierItem.getBackOfferId(), supplierItem.getWarehouseIdList());
} else {
OfferModel backOffer = backOfferQueryService.getBackOffer(supplierItem.getBackOfferId());
if (backOffer != null) {
sellableAmount = backOffer.getOffer().getTradeModel().getTradeCondition().getAmountOnSale();
}
}
if (sellableAmount < 1) {
throw ExceptionFactory.makeFault(ServiceExceptionCode.SYSTEM_ERROR, "Stock must be > 0 to publish, please replenish. [id:" + supplierItem.getId() + "]");
}
}After introducing a domain model, the code simplifies dramatically:
if (backOffer.isCloudWarehouse()) {
return;
}
if (backOffer.isNonInWarehouse()) {
throw new BizException("Cannot publish Offer, contact warehouse operations!");
}
if (backOffer.getStockAmount() < 1) {
throw new BizException("Stock must be > 0 to publish, please replenish. [id:" + backOffer.getSupplierItem().getCspuCode() + "]");
}Using models makes the logic clearer and eliminates most if‑else checks through polymorphism (e.g., CombineBackOffer extends BackOffer).
Process Decomposition + Object Model
Combining structured decomposition with object modeling yields a system structure that is both clean and expressive, as shown in the diagram.
Methodology for Writing Complex Business Code
The key is "top‑down structured decomposition + bottom‑up object analysis".
Next, we refine this case into a practical methodology that can be generalized to other complex scenarios.
Top‑Down and Bottom‑Up
This approach combines top‑down process decomposition with bottom‑up object modeling in a spiral fashion, allowing the two steps to alternate or occur simultaneously.
The two steps complement each other: analysis clarifies model relationships, while modeling improves code reuse and business semantics.
Capability Sinking
Practicing DDD involves two stages: first, learning concepts and using Aggregates, Repositories, etc.; second, internalizing the essence—ubiquitous language, bounded contexts, and object‑oriented analysis.
Rather than forcing all business logic into the Domain layer, we should adopt a pragmatic "capability sinking" strategy: only abstract capabilities that need reuse across scenarios into the Domain, leaving use‑case‑specific logic in the Application layer.
Guidelines for sinking: reuse indicates *when* to sink, and cohesion indicates *where* to sink (Domain Service vs. Domain Model).
For example, in the product domain, checks like "isMinimumUnit" or "isMidPackage" belong on the model itself.
public class CSPU {
private String code;
private String baseCode;
// ...
public boolean isMinimumUnit() {
return StringUtils.equals(code, baseCode);
}
public boolean isMidPackage() {
return StringUtils.equals(code, midPackageCode);
}
}Previously, such checks were scattered as utility calls, making the code hard to understand.
What Business‑Tech Should Do
Business‑tech faces complex, rapidly changing domains, requiring the same core abilities as low‑level engineers: problem decomposition, abstraction, and structured thinking.
By solidifying foundational technical skills, OO capabilities, and modeling expertise, business‑tech can write highly technical, maintainable code.
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.
Alibaba Cloud Developer
Alibaba's official tech channel, featuring all of its technology innovations.
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.
