2025-10-27
Who first saw the moon by the riverbank? In what year did the river moon first shine upon man? — “Spring River, Flower, Moon, Night” · Zhang Ruoxu, Tang Dynasty
Details
Full Poem
The tide of the spring river rises with the sea, and on the sea the bright moon ascends with the tide.Its shimmering light follows the waves for thousands of miles—where along the spring river is the moon not bright?
The winding river encircles fragrant meadows; the moonlight over flowered woods glitters like frost.
In the air, drifting frost seems to fly unseen; on the sandbanks, white sands vanish under the glow.
The river and sky merge in a dustless hue, and high above hangs a lone bright moon.
Who first saw the moon by the riverbank? In what year did the river moon first shine upon man?
Generation after generation, life never ceases, yet the river moon remains ever the same.
Who does the river moon wait for, none can say; only the flowing river carries on unendingly.
A patch of white cloud drifts endlessly away; on the Green Maple Bank, sorrow abounds.
Whose boat sails tonight upon the river? Whose beloved gazes at the moon from her lofty chamber?
Pity the moon that lingers above the tower, shining upon a lonely one before her mirror stand.
Through jade windows, the moonlight cannot be rolled away; on the stone anvil, where clothes are pounded, it brushes again.
Now they gaze at each other through moonlight, yet cannot hear each other’s voice—
May the moon’s glow flow along the river, reaching where my love abides.
Geese fly long, yet the light cannot cross to them; fish and dragons leap beneath, tracing patterns in the waves.
Last night, by a quiet pond, I dreamed of falling blossoms—pity that halfway through spring, I still am not home.
The spring river flows on and is about to fade; the setting moon dips westward over the riverbank.
The slanted moon sinks into sea mist; the path from Jieshi to Xiaoxiang stretches endlessly.
Who among the moonlit travelers will return home tonight? The sinking moon stirs sorrow through riverside trees.
Study Notes on Design Patterns and Engineering Principles in Code Refactoring
I. Overview
The goal of this refactoring was not to alter business logic, but to optimize the structure of the code—enhancing readability, scalability, and maintainability. Throughout the process, multiple classic design patterns and engineering principles were applied, including:
- Facade Pattern
- DTO (Data Transfer Object) Pattern
- Value Object Pattern
- Adapter / Anti-Corruption Layer
- Interface Segregation Principle
- Composition over Inheritance
- Defensive Programming (Guard Clauses)
These concepts complement each other, producing a clean architecture with clear responsibilities and strong extensibility.
II. Key Patterns and Principles Explained
1. Facade Pattern
Core Idea: Provide a unified interface for a complex subsystem, so that upper layers need not know internal details.
Application in this project:
- The
Serviceclass acts as a façade, exposing simple business methods; - Internally handles execution flow, exception handling, logging, and validation;
- External modules can complete entire business operations through a single call.
Advantages:
- Simplifies calling code;
- Shields internal complexity;
- Facilitates testing and maintenance.
2. DTO (Data Transfer Object) Pattern
Core Idea: A simple object used for data transfer between systems; it contains no business logic, only data encapsulation.
Design Points:
- All input/output data are wrapped in DTOs;
- Use generic DTOs to increase flexibility;
- Employ JSON annotations and serialization tools for automatic mapping.
Advantages:
- Decouples data structure from business logic;
- Easy to extend with new fields;
- Enables high reusability through generic design.
3. Value Object Pattern
Core Idea: Encapsulates immutable data that represents value rather than identity.
Example Implementation:
private record Sec(String token, String cookie) {}
Features:
- Immutable (fields in
recordarefinal); - Auto-generates constructor, accessors,
equals, andhashCode; - Expressive and concise.
Advantages:
- No side effects;
- Safe and reusable;
- Clean, pure logic representation.
4. Adapter / Anti-Corruption Layer
Core Idea: When external systems or data formats differ, introduce an adapter layer to translate them into a unified internal structure.
Design Points:
- Use intermediate DTOs (e.g.,
ODataResponse<T>) to hide external formats; - Internal code only interacts with unified models;
- If external APIs change, only the adapter layer needs modification.
Advantages:
- Prevents external dependencies from polluting internal code;
- Reduces impact of external changes;
- Improves overall stability.
5. Interface Segregation Principle (ISP)
Core Idea: An interface should only include methods relevant to the implementing class; it should not force dependency on unnecessary functionality.
Implementation Example:
public interface HasStatusMessage {
String getStatus();
String getMessage();
}
Design Intention:
- Avoid using inheritance for common base behavior;
- Restrict to minimal essential capabilities (status and message retrieval);
- Allow any object to be uniformly processed by implementing this interface.
Advantages:
- Lower coupling;
- Easier to extend;
- Greater flexibility.
6. Composition over Inheritance
Core Idea: Prefer composition for code reuse instead of class inheritance.
Before Refactoring:
public class TableResult extends Result { ... }
public class MaskResponse extends Result { ... }
After Refactoring:
public class TableResult implements HasStatusMessage { ... }
public class MaskResponse implements HasStatusMessage { ... }
Advantages:
- Shallower inheritance hierarchy;
- Avoids base-class pollution;
- Allows flexible implementation of shared behavior;
- Easier testing and maintenance.
7. Defensive Programming (Guard Clauses)
Core Idea: Validate preconditions at the start of a method; if unmet, exit immediately.
Example:
private void ensureHttpOk(ResponseEntity<?> response) {
if (response.getStatusCode().isError()) {
throw new IllegalStateException("HTTP request failed");
}
if (response.getBody() == null) {
throw new IllegalArgumentException("Response body is null");
}
}
Advantages:
- Detects errors early;
- Clarifies logical flow;
- Avoids deep nesting with
if-else.
III. Overall Structure Diagram
┌───────────────────────────────┐
│ Service (Facade) │
│ ├─ Workflow orchestration │
│ ├─ Unified error/log handling│
│ └─ Standardized DTO output │
└────────────┬──────────────────┘
│ uses
┌────────────▼──────────────────┐
│ Adapter / DTO Layer │
│ ODataResponse<T> │
│ Converts external formats │
└────────────┬──────────────────┘
│
┌────────────▼──────────────────┐
│ Result Classes Implementing │
│ (HasStatusMessage) │
└───────────────────────────────┘
IV. Summary of Design Principles
| Pattern / Principle | Core Goal | Application Example |
|---|---|---|
| Facade | Simplify interface | Service encapsulates full workflow |
| DTO | Decouple data transfer | ODataResponse<T>, Result |
| Value Object | Express immutable data | record Sec(...) |
| Adapter / ACL | Shield external differences | Unified external structure parsing |
| Interface Segregation | Minimize dependency | HasStatusMessage |
| Composition over Inheritance | Reduce coupling | implements instead of extends |
| Defensive Programming | Improve robustness | ensureOk* methods |
V. Key Takeaways
- Define responsibilities before reusability — Each class should have one clear purpose;
- Interfaces express capability, classes express identity — Interfaces are more flexible than inheritance;
- Decouple internal models from external protocols — Protect internal stability from external changes;
- Prefer localized encapsulation over global exposure — Keep utility types like
record Secprivate; - Simplicity is strength — Clear boundaries are more valuable than deep hierarchies.
VI. Conclusion
The core philosophy of this refactoring is:
Let responsibilities define the boundaries, and use patterns to solve problems—not to decorate design.
By applying patterns such as Facade, DTO, Value Object, and Interface Segregation, the refactored code achieves higher cohesion and lower coupling. The result is not only a more elegant structure, but also one that is easier to extend, debug, and test in the future.