Overview of Software Complexity and Strategies for Reducing Business System Complexity
The article explains the concept and measurement of software complexity, its impact on development cost and stability, common causes in business systems, and presents a set of architectural, coding, and configuration practices—including domain splitting, layered design, clear commenting, and configurable rules—to effectively reduce and manage complexity.
Complexity is a core concern in software design; there is no unified definition, but Stanford professor John Ousterhout proposes a formula based on cognitive load and work effort.
The article defines a module’s complexity cp and overall system complexity C as the sum of cp multiplied by a development‑time weight tp , noting that rarely used but complex modules have limited impact on the total.
High business complexity leads to increased development cost and reduced stability, with common causes such as many inter‑dependent modules, obscure code that hides key information, and frequently changing business rules.
To lower complexity, the article recommends abstract divide‑and‑conquer methods: domain splitting (separating entity, process, and computation domains), intra‑domain splitting (stable vs. variable parts, B/C scenario isolation), and internal subsystem decomposition (layered architecture, single‑responsibility methods). Examples include separating core concepts into independent domains and applying the “stable‑unstable” split in a marketing system.
It also advocates structured top‑down decomposition using the pyramid principle, adding clear comments that explain the what and why of code, and making business objects, rules, and workflows configurable through rule engines or configuration centers.
Enforcing coding and architectural conventions—such as consistent naming, layered responsibilities (access, business‑logic, domain‑service, data layers), and avoiding cross‑layer calls—further reduces cognitive load.
Practical code examples illustrate these practices:
/**
* 处理业务逻辑
*/
public void handleBiz(){
step1();
step2();
step3();
}and
/**
* 转换对象方法
*/
public Po convert(Dto dto){
Po po = new Po();
po.field = dto.filed;
// 更新操作,不应该放到转换方法里
mapper.update(po);
// 调用rpc服务,不应该放到转换方法里
XXGateway.update(dto);
return po;
}and a layered service method example:
@Override
public InsertDeptResponse insertDept(InsertDeptRequest request) {
// 入参记录
log.error("insertDept request:{}", request);
InsertDeptResponse response = null;
String umpKey = XXX;
Profiler.registerInfo(umpKey, true, true);
try {
// 校验入参
checkParam(request);
// 权限校验
checkAuth();
// 业务逻辑处理
response = XXFacade.insertDept(request);
} catch (BizRuntimeException ce) {
// 不影响可用性的异常
log.error("XXX");
response = XXX;
} catch (Exception e) {
// 影响可用性的异常
log.error("XXX");
response = XXX;
Profiler.functionError(info);
}
log.error("insertDept response:{}", response);
Profiler.registerInfoEnd(info);
return response;
}Finally, the article lists refactoring principles such as small incremental releases, “write‑first‑read‑later” validation, and tackling lightweight logic before heavyweight logic to ensure safe and effective complexity reduction.
JD Tech Talk
Official JD Tech public account delivering best practices and technology innovation.
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.