Transform Spaghetti Code into Clean Architecture with 3 Powerful Patterns
This article redefines what constitutes good code by using a star‑chart analogy, exposing typical spaghetti‑code pitfalls, and introducing three design patterns—Value Object, Side‑Effect‑Free Function, and Intention‑Revealing Interface—to help developers refactor and write maintainable software.
Purpose of the Noodle Code Series
The first article of the series starts from theory and, through practice, explores how to write good code, aiming to shift readers' perception of what constitutes quality code.
What Is Good Code?
Good code can be described from many dimensions such as abstraction level, extensibility, readability, and design‑pattern compliance, but the article introduces a new perspective: code should model business knowledge completely, much like an ancient star chart models celestial movements.
Origin of Spaghetti Code
Spaghetti code refers to unstructured, hard‑to‑maintain source code. An example requirement is presented: a personnel sign‑in system where sign‑in after a configurable tolerance period is marked late.
人员签到的需求:</code><code>* 当签到时间>班次开始时间N分钟后,签到状态为迟到</code><code>* N根据不同的业务可以灵活配置,比如:门店为5,配送为0The initial implementation is shown:
public void 人员签到(班次ID,人员ID) {</code><code> 班次 = 班次Repo.获取班次(班次ID)</code><code> 迟到可容忍时间 = 配置服务.获取可容忍时间(业务域);</code><code> 签到状态 = null;</code><code> if(签到时间 > (班次.开始时间 +迟到可容忍时间)) {</code><code> 签到状态 = 迟到;</code><code> } else {</code><code> 签到状态 = 正常;</code><code> }</code><code> //更新数据库状态</code><code>}Two main problems are identified:
The method repeatedly queries a configuration service, leading to long, tangled methods.
The business logic is mixed directly into the method, creating procedural code that becomes increasingly complex.
How to Solve Spaghetti Code
The article proposes three patterns:
Value Object : Encapsulate configuration (e.g., tolerance time) into an immutable object attached to the domain model, eliminating repeated service calls.
Side‑Effect‑Free Function : Place pure functions on value objects so they do not modify system state and can be trusted.
Intention‑Revealing Interface : Name methods and interfaces using the ubiquitous language of the business, making their purpose clear without extra communication.
Pattern One: Value Object
Instead of fetching tolerance time at sign‑in, embed it in a 班次配置 value object when the shift is created, so the shift itself knows the tolerance.
Pattern Two: Side‑Effect‑Free Function
Move the attendance‑status determination into a pure method on the 班次 value object:
public class 班次 {</code><code> 班次配置;</code><code> 开始时间;</code><code> 结束时间;</code><code> 签到状态判定(签到时间) {</code><code> if(签到时间 > (开始时间 +班次配置.迟到可容忍时间)) {</code><code> return 迟到;</code><code> } else {</code><code> return 正常;</code><code> }</code><code> }</code><code>}Pattern Three: Intention‑Revealing Interface
Use business‑centric names for methods and interfaces so that anyone reading the code immediately understands its purpose, aligning with Domain‑Driven Design's “ubiquitous language”.
Summary
The article aims to refresh readers' understanding of good code, presenting three patterns—Value Object, Side‑Effect‑Free Function, and Intention‑Revealing Interface—to refactor spaghetti code into maintainable, expressive software. It also provides before‑and‑after code snippets and a diagram illustrating the transformation.
Further Reading
Domain‑Driven Design: https://book.douban.com/subject/26819666
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.
