Part 4: Component Cohesion Principles
The summary of Uncle Bob’s great book “Clean Architecture”
Component cohesion:
It helps us to understand which classes should go into which component.
The three principles of component cohesion:
- REP: The Reuse/Release Equivalence Principle
- CCP: The Common Closure Principle
- CRP: The Common Reuse Principle
THE REUSE/RELEASE EQUIVALENCE PRINCIPLE
This principle means that the classes and modules that are formed into a component must belong to a cohesive group. The component cannot simply consist of a random hodgepodge of classes and modules; instead, there must be some overarching theme or purpose that those modules all share.
Classes and modules that are grouped together into a component should be releasable together. The fact that
- They share the same version number and the same release tracking
- They are included under the same release documentation
- They should make sense both to the author and to the users.
THE COMMON CLOSURE PRINCIPLE
Gather into components those classes that change for the same reasons and at the same times.
Separate into different components those classes that change at different times and for different reasons.
A component should not have multiple reasons to change.
The CCP prompts us to gather together in one place all the classes that are likely to change for the same reasons.
This minimizes the workload related to releasing, revalidating, and redeploying the software.
Gather together those things that change at the same times and for the same reasons. Separate those things that change at different times or for different reasons.
THE COMMON REUSE PRINCIPLE
Don’t force users of a component to depend on things they don’t need.
These classes belong together in the same component. In such a component we would expect to see classes that have lots of dependencies on each other. It also tells us which classes not to keep together in a component.
A simple example might be a container class and its associated iterators. These classes are reused together because they are tightly coupled to each other. Thus they ought to be in the same component.
The CRP says that classes that are not tightly bound to each other should not be in the same component.
Component coupling:
It implies how components should relate to one another
Acyclic Dependencies Principle (ADP): Components should not create cyclic dependencies. This principle ensures that the dependencies between components form a directed acyclic graph, which makes it easier to reason about the system’s behavior and reduce coupling.
Top-Down Design
The component structure cannot be designed from the top down. It is not one of the first things about the system that is designed, but rather evolves as the system grows and changes.
Component dependency diagrams have very little do to with describing the function of the application. Instead, they are a map to the buildability and maintainability of the application. This is why they aren’t designed at the beginning of the project.
The component dependency graph is created and molded by architects to protect stable high-value components from volatile components.
THE STABLE DEPENDENCIES PRINCIPLE
It states that the dependencies between software modules should be in the direction of stability. In other words, a module should only depend on other modules that are more stable than itself. A module’s stability is determined by how frequently it changes. If a module changes frequently, it is considered less stable, and if it changes infrequently, it is considered more stable. Stable modules are those that are unlikely to change frequently, such as libraries or frameworks, whereas unstable modules are those that are subject to frequent changes, such as application-specific code.
Depend in the direction of stability.
Stability is related to the amount of work required to make a change. The stability of a module refers to how frequently it changes.
THE STABLE ABSTRACTIONS PRINCIPLE
A component should be as abstract as it is stable.
In other words, the level of abstraction of a module should be in proportion to its stability.
The goal of the Stable Abstractions Principle is to create a system in which highly abstract modules are the most stable, while less abstract modules are more likely to change. This is because highly abstract modules tend to have a wider range of uses and are more fundamental to the system, whereas less abstract modules tend to be more application-specific and subject to frequent change.
To implement the Stable Abstractions Principle, it is important to carefully analyze the functionality of each module and determine its level of abstraction and stability. Highly abstract modules should be designed to be stable, with a well-defined interface that is unlikely to change frequently. Less abstract modules should be designed to be more flexible, with a more specific interface that can be easily adapted to changing requirements.
By following the Stable Abstractions Principle, software developers can create systems that are more flexible and easier to maintain over time. Highly abstract modules provide a stable foundation for the system, while less abstract modules can be easily modified to meet changing requirements without affecting the overall stability of the system.