Clean Architecture Notes - SOLID (Part 2)

Search for a command to run...

No comments yet. Be the first to comment.
1. Sạch Phải công nhận là Sing sạch, đi đâu cũng thấy có người đang quét dọn, tỉa cành, gom rác, cắt cỏ,… Chi phí để duy trì môi trường cảnh quan chắc cũng không hề nhỏ. 2. Giao thông công cộng Bên này chủ yếu đi bằng tàu điện (MRT) và xe bus, chi ph...
In the previous article, I covered the basic concepts and introduced a 5-step process for applying DDD in practice. Today, I will bring you a bigger challenge. In this article, we will work through an

I. Why DDD matters? A Bigger Picture Over the years, as business needs have grown increasingly complex, our application systems have evolved - from monoliths to SOA, and now to microservices. This evolution demands a rational approach to component de...

Behind every robust software system lies a suite of well-structured unit tests. But what defines a great unit test? In this article, we’ll examine its anatomy and best practices to ensure your tests are both reliable and effective. I. A Bigger Pictur...

This is a nice feedback from my Singaporean Scrum Master for 2024. According to Vietnamese beliefs, 2024 marked the final year of a challenging three-year period (Tam Tai) for those born in 1996, a time filled with uncertainties and difficulties. Al...
You could follow the previous post here
To build a building, we need bricks. On the one hand, if the bricks aren’t well made, the architecture of the building doesn’t matter much. On the other hand, you can make a substantial mess with well-made bricks.

Good software systems begin with clean code. The SOLID principles tell us how to arrange our functions and data structures into classes, and how those classes should be interconnected
Or you could say:
The SOLID principles tell us how to arrange the bricks into walls and rooms
The goal of the principles is the creation of mid-level software structures (module level) that:
• Tolerate change
• Are easy to understand
• Are the basis of components that can be used in many software systems
=> So that each one has only one reason to change


The goal is to make the system easy to extend without incurring a high impact of change. This goal is accomplished by partitioning the system into components, and arranging those components into a dependency hierarchy that protects higher-level components from changes in lower-level components.

=> if there is any change on the module that you depend on, could lead to recompiled and redeployed, even though nothing that it cared about has actually changed.
Ex: In Java, we have 2 classes which implement 1 interface. And each class need only one method from that interface.

The design violated the ISP so the source code of User 1 will inadvertently depend on op2 and op3, even though it doesn’t call them.
=> segregating your big interface into smaller and more specific ones.
The Dependency Inversion Principle (DIP) tells us that the most flexible systems are those in which source code dependencies refer only to abstractions, not to concretions.
Don’t derive from volatile concrete classes
Don’t override concrete functions:
Concrete functions often require source code dependencies. When you override those functions, you do not eliminate those dependencies—indeed, you inherit them. To manage those dependencies, you should make the function abstract and create multiple implementations.
=> should create an interface and implement it.
And how to deal with that? We could use Abstract Factory pattern to deal with the creation of volatile concrete objects.
Ex: The Application uses the ConcreteImpl through the Service interface. However, the Application must somehow create instances of the ConcreteImpl.
To achieve this without creating a source code dependency on the ConcreteImpl, the Application calls the makeSvc method of the ServiceFactory interface. This method is implemented by the ServiceFactoryImpl class, which derives from ServiceFactory. That implementation instantiates the ConcreteImpl and returns it as a Service.

You could see that the curve line separates the abstract from the concrete. And the important thing is:
All source code dependencies cross that curved line pointing in the same direction, toward the abstract side
And the source code dependencies are inverted against the flow of control - which is why we refer to this principle as Dependency Inversion.
(to be continued)