Skip to main content

2025-10-27

Quote

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 Service class 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 record are final);
  • Auto-generates constructor, accessors, equals, and hashCode;
  • 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 / PrincipleCore GoalApplication Example
FacadeSimplify interfaceService encapsulates full workflow
DTODecouple data transferODataResponse<T>, Result
Value ObjectExpress immutable datarecord Sec(...)
Adapter / ACLShield external differencesUnified external structure parsing
Interface SegregationMinimize dependencyHasStatusMessage
Composition over InheritanceReduce couplingimplements instead of extends
Defensive ProgrammingImprove robustnessensureOk* methods

V. Key Takeaways

  1. Define responsibilities before reusability — Each class should have one clear purpose;
  2. Interfaces express capability, classes express identity — Interfaces are more flexible than inheritance;
  3. Decouple internal models from external protocols — Protect internal stability from external changes;
  4. Prefer localized encapsulation over global exposure — Keep utility types like record Sec private;
  5. 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.