Design Principles and Decoupled Deployment for Backend Systems
This article summarizes SOLID and component design principles, explains how to evaluate and balance component stability, coupling, and abstraction, and describes source‑code, library, and service‑level decoupled deployment strategies for building maintainable backend architectures.
Background
The author, a backend engineer at Tencent IEG Growth Platform, writes this article after experiencing painful code changes in early projects that lacked any design principles; after studying SOLID, component design, and decoupled deployment, he shares the lessons learned and theoretical guidelines that can be applied to any system.
Code Design Principles
SRP – Single Responsibility Principle
A class should be modified for only one reason, preventing changes for one user from affecting another; the principle is often misinterpreted as “one class does one thing,” which is a useful but incomplete view.
OCP – Open/Closed Principle
New functionality should be added by extending code rather than modifying existing code, typically achieved by defining interfaces and plugging in low‑level implementations.
LSP – Liskov Substitution Principle
Derived classes must be replaceable for their base class without breaking the program, ensuring inheritance does not increase complexity and that base classes remain reusable.
ISP – Interface Segregation Principle
Clients should not depend on interfaces they do not use; keep interfaces small and focused.
A class should depend on the minimal interface needed.
Build single‑purpose interfaces rather than large, bloated ones.
Refine interfaces so they contain as few methods as possible.
DIP – Dependency Inversion Principle
High‑level modules should not depend on low‑level modules; both should depend on abstractions. For example, instead of core code directly calling Redis, define a cache interface in the core and let Redis (or any other cache) implement it, allowing easy replacement without changing core business logic.
Assuming we replace Redis with Tendis, the core code would otherwise need to be modified; with DIP, only the new cache implementation changes.
By keeping the core stable and treating caches as plugins, the risk of changes is greatly reduced.
Component Design Principles
Components are the smallest deployable units that encapsulate data and behavior. The following principles guide how to group code into components.
1. Design Principles for Component Composition
1.1 REP – Reuse‑Equals‑Publish Principle
The smallest reusable unit should be the same as the smallest publishable unit; versioning and deployment should align with component boundaries.
1.2 CCP – Common Closure Principle
Classes that change together for the same purpose should be placed in the same component, while unrelated classes belong to different components.
1.3 CRP – Common Reuse Principle
Do not force users to depend on things they do not need; avoid placing unnecessary classes in a component that a client uses.
1.4 Relationship Among Principles
REP, CCP, and CRP can conflict; early in a project, CCP may dominate to speed development, while later the focus shifts toward REP for long‑term reuse.
2. Design Principles for Component Coupling
2.1 No Dependency Cycle Principle
A component graph must be acyclic; otherwise, changes can cause endless circular updates and high coordination cost.
When cycles exist, developers must coordinate simultaneous changes across all involved components, dramatically increasing effort.
2.2 Stable Dependency Principle
Components that are depended upon should be more stable than the components that depend on them.
2.3 Stable Abstraction Principle
A component’s level of abstraction should match its stability: highly stable components should be highly abstract, while unstable ones can contain more concrete implementations.
Metrics such as I(A) = o(A)/(o(A)+i(A)) for stability and A = Na/Nc for abstraction can be combined into D = |A + I – 1| to quantify adherence to the principle.
Reasonable Decoupled Deployment
After applying design principles, the article discusses three levels of decoupled deployment without detailing specific steps.
Source‑Code Level Decoupling (Monolith)
Modules are separated within a single process, managing dependencies so changes in one module minimally affect others.
Library Level Decoupling
Similar to the monolith but with distinct code libraries that can be versioned and upgraded independently, sometimes communicating via IPC.
Service Level Decoupling
Components run in separate services communicating over the network (e.g., gRPC); this provides the strongest isolation, typical of SOA or micro‑service architectures.
Choosing a Deployment Strategy
The appropriate level depends on business needs; premature micro‑service adoption can introduce unnecessary cost, latency, and complexity. Early stages often start with source‑code level decoupling, evolving to libraries or services as the system grows.
Personal Reflections
Design principles are valuable guidelines distilled from long‑term practice, but they are not absolute rules; trade‑offs are necessary based on project size, timeline, and maintenance expectations. Long‑lived systems benefit most from strict adherence, while short‑lived or experimental projects may relax some constraints.
References
[1] Clean Architecture – https://github.com/sdcuike/Clean-Code-Collection-Books/blob/master/Clean%20Architecture%20A%20Craftsman's%20Guide%20to%20Software%20Structure%20and%20Design.pdf
[2] Object‑Oriented Software Construction – https://web.uettaxila.edu.pk/CMS/AUT2011/seSCbs/tutorial/Object%20Oriented%20Software%20Construction.pdf
[3] Make LSP Work for You – https://yuanshenjian.cn/make-lsp-working-for-you/
[4] Liskov Substitution Principle – https://geek-docs.com/design-pattern/design-principle/liskov-substitution-principle.html
[5] Design Patterns and the Seven Principles – https://cloud.tencent.com/developer/article/1650116
IEG Growth Platform Technology Team
Official account of Tencent IEG Growth Platform Technology Team, showcasing cutting‑edge achievements across front‑end, back‑end, client, algorithm, testing and other domains.
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.