Designing Good System Architecture: Isolation, Concerns, and AOP
The article explains how to design clean, decoupled system architectures by isolating concerns, using AOP, dependency injection, factory methods, and DSLs, while illustrating concepts with city‑building analogies and Java code examples.
This chapter discusses how to design a good system architecture, emphasizing the principle of isolation (concern separation) across all abstraction layers.
Conclusion
Overall architecture should be simple and elegant, ensuring decoupling between abstraction layers.
Each layer must have a clear purpose (single responsibility, non‑intrusive); achieve this with AOP.
Always prefer the simplest implementation when designing systems or modules.
Building a system is likened to building a city: isolation of concerns and multiple abstraction layers enable efficient management.
Distinguish between building a system and using it; the startup phase focuses on different concerns than the runtime phase.
Example of lazy‑initialization code (code 10‑1):
//代码10-1
public Service getService() {
if (service == null)
service = new MyServiceImpl(...); // Good enough default for most cases?
return service;
}This pattern introduces tight coupling and testing difficulties; extracting initialization into separate components is recommended.
Separation via main()
Placing all initialization in main() centralizes object creation, but can waste resources.
Separation via Factory Method
Using an abstract factory lets the program decide when to create objects while keeping creation details separate.
Dependency Injection
DI encapsulates object creation and assembly in dedicated containers, enforcing the single‑responsibility principle.
Scaling (Scale Up)
Systems evolve from small to large; focus on current needs and iteratively refactor and extend.
Techniques like TDD, refactoring, and clean code support progressive expansion.
EJB examples illustrate tight coupling problems that hinder testing and inheritance.
Aspect‑Oriented Programming (AOP)
Cross‑cutting concerns (e.g., persistence, security, transactions) are best handled with AOP. Three Java AOP solutions are presented:
Java Proxy (requires interfaces; otherwise use CGLIB, ASM, Javassist).
Pure Java AOP frameworks such as Spring AOP.
AspectJ, which offers richer capabilities but requires new tools and language constructs.
Using AOP enables test‑driven architecture by keeping core logic simple and decoupled.
Avoid big‑design‑up‑front (BDUF); instead, make decisions as late as possible based on the best available knowledge.
Adopt standards wisely; when better solutions exist, don’t follow standards rigidly.
Domain‑Specific Languages (DSLs) can abstract system concepts, freeing designers from implementation details.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
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.