Component Principles - vanskarner/CleanMovie GitHub Wiki

Spanish

Components for principles can be viewed as the grouping of classes or other software artifacts that have a single purpose within a system and can be linked to other components.

On the other hand, component principles are indications of how to build and relate components in an architecture. There are two types of principles: Cohesion Principles and Coupling Principles, each composed of three principles:

Principles of Component Cohesion

Principles that determine the assignment of classes or other software artifacts in a component.

REP: Reuse/Release Equivalence Principle

The granule of reuse is the granule of release.

- Robert C. Martin (Uncle Bob), Clean Architecture: A Craftsman’s Guide to Software Structure and Design, 2017

A component must be composed of software artifacts that share a purpose and a meaningful reason to be together for release.

CCP: 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.

- Robert C. Martin (Uncle Bob), Clean Architecture: A Craftsman’s Guide to Software Structure and Design, 2017

A component must have a closure strategy to minimize possible changes in the face of a change in requirements.

This principle is an extension of SRP, as it aligns with the description: "A component should not have multiple reasons to change". Furthermore, it is related to OCP, as it aligns with the description: "Bring together in the same component that which is closed to the same types of change".

CRP: Common Reuse Principle

Don’t force users of a component to depend on things they don’t need.

- Robert C. Martin (Uncle Bob), Clean Architecture: A Craftsman’s Guide to Software Structure and Design, 2017

A component should contain software artifacts that tend to be reused together, while those that are not closely linked to each other should not be part of the component.

This principle is an extension of ISP, as it aligns with the description: "Do not depend on components that have classes or modules that you do not need".

Tension Diagram of the Cohesion Principles

The following diagram was created based on the one presented in the book Clean Architecture: A Craftsman's Guide to Software Structure and Design (2017) and only a few elements were added.

Diagram
This diagram represents the conflicting effects of the 3 cohesion principles when structuring components and helps us to identify and balance certain architectural concerns. For example, if we focus only on the CCP and CRP principles, the result will be a component that is difficult to reuse. It is also noted that following the REP and CCP principles increases the size of the component, while following the CRP principle does the opposite.
TensionDiagramCohesionPrinciples

It is important to note that the structure of the components must respond to the current need, which is more related to the way the project is developed and used than to its actual functionality. Therefore, components will be placed in different positions in the diagram as the software system evolves and matures over time.

Principles of Component Coupling

Principles that define how the components are related.

ADP: Acyclic Dependencies Principle

Allow no cycles in the component dependency graph.

- Robert C. Martin (Uncle Bob), Clean Architecture: A Craftsman’s Guide to Software Structure and Design, 2017

The dependency between components must be free of cycles, either by creating a new component or by applying dependency inversion to break the cycles.

ADP Violation Solution 1: Create a new component
We can see that there is a cycle represented by red arrows between the User, Project and Authorization components, which is a violation of this principle. To break this cycle, a new component can be created in which the common elements for Project and Authorization would be placed. In this way, both components would depend on the new component Permissions

ADP Violation

ADP Solution 1

Solution 2: Dependency inversion
Another way to break this cycle is to resort to dependency inversion. For example, the Project component declares the services it needs, as in the case of Permissions, and the Authorization component implements that service.

ADP Solution 2

SDP: Stable Dependencies Principle

Depend in the direction of stability.

- Robert C. Martin (Uncle Bob), Clean Architecture: A Craftsman’s Guide to Software Structure and Design, 2017

Any volatile component should not depend on another component that is difficult to change, as it will also become complicated to change.

SDP aims at stability, where a component is considered stable when several other components depend on it, while it is considered unstable when it has no components that use it.

Example: Stable and Unstable Component
image

Metrics in SDP

SDP has a formula called Instability (I) and states that the metric I of a component must be greater than the metric I of the components on which it depends.

Formula Description
$I=\displaystyle\frac{Fan-out}{Fan-in + Fan-out}$ I: Instability
Fan-in: Number of external classes with incoming dependencies
Fan-out: Number of internal classes with outgoing dependencies

Where:
I : range [0,1]
I = 0 : Maximum stable component
I = 1 : Maximum unstable component
Example: Calculating the metric in the User component
Metrics in Component User::
The value of Fan-in is 3
The value of Fan-out is 1
Therefore: $I=\displaystyle\frac{1}{3 + 1}$ = $\displaystyle\frac{1}{4}$ = 0.25

It is useful when diagramming to place the changeable (unstable) components at the top, as shown with the Presentation and Persistence components, because if we notice arrows pointing upwards, they would imply a violation of the SDP and also of ADP. This is because stable components should not depend on unstable components.
ApplyingSDP
PDS violation
In this case, the Authentication component is designed to be easily modified (unstable) when necessary. However, someone in charge of the User component has established a dependency on Authentication, which causes any changes to Authentication to impact User and its dependents. Furthermore, if we compare the metrics of 0.33 for User and 1 for Authentication, this indicates an SDP violation.

SDP Violation

Solution to the above problem
We can solve this problem by applying dependency inversion, which would result in the creation of a new abstract component called GeneralServices. In this abstract component, we place the abstraction that will use User and the one that will implement Authentication, so that the metrics for each component match. These abstract components are a common tactic in statically typed languages such as C# and Java, but do not exist in dynamically typed languages such as JavaScript and Python, as they do not require it.

SDP Solution

SAP: Stable Abstractions Principle

A component should be as abstract as it is stable.

- Robert C. Martin (Uncle Bob), Clean Architecture: A Craftsman’s Guide to Software Structure and Design, 2017

A stable component must be abstract to allow its extension through the use of interfaces, abstract classes or other abstract artifacts, and is oriented to encapsulate high-level policies. On the other hand, an unstable component must be concrete and include volatile software that can be easily changed.

This principle in conjunction with SDP is an extension of DIP for components.

Metrics in SAP

SAP has the Abstractness (A) formula and its value represents the ratio of interfaces and abstract classes in a component to the total number of classes in the component.

Formula Description
$A=\displaystyle\frac{Na}{Nc}$ A: Abstractness
Na: Number of abstract classes and interfaces in the component
Nc: Number of classes in total of the component

Where:
A : range [0,1]
A = 0 : Maximum concrete component
A = 1 : Maximum abstract component
Example: Calculating the metric in the User component
Metrics in Component User:
The value of Na is 3
The value of Nc is 6
Therefore: $A=\displaystyle\frac{3}{6}$ = 0.5

It can be observed that the User and Publication components are as stable as they are abstract. This abstraction allows them to be extended and, in addition, these components include high-level policies.
SAP_Example

Instability/Abstractness Graph

The following graphic is based on the one shown in the book Clean Architecture: A Craftsman's Guide to Software Structure and Design (2017). It helps us identify the areas to target (green zone) and the areas to avoid (red zone) when distributing the metrics shown in SDP and SAP for each component.

Instability/Abstractness Graph

🟥 Exclusion Zones: In general, avoid having your components in the zone of pain and in the zone of futility.

  • Pain zone: The components located here are difficult to change and extend. In this area you can find database schemas, utility libraries, among others.
  • Zone of Uselessness: The components located here are unused software elements because they are very abstract and without dependencies. Interfaces or abstract classes that were never implemented can be found in this area.

🟩 The Main Sequence: This is the most desirable area where the components should be located. We should aim at the ends of the main sequence (green dots) or close to it (green line).

Example: Locating components on the Instability/Abstraction Graph
It is essential to emphasize that this example is merely illustrative. To achieve a more adequate representation, it would be necessary to include many more components, and within these components, many more software elements.
SDP_SAP_LocationDiagram

Main Sequence Distance Metric

This metric represents how far a component is from the Main Sequence. If the D metric of a component is not close to zero, it is advisable to review it and, if necessary, restructure it.

Formula Description
$D= \left|A+I-1\right|$ D: Main Sequence Distance
A: SAP Metric
I: SDP Metric

Where:
D : range [0,1]
D = 0 : The component is directly in the main sequence
D = 1 : The component is as far away from the main sequence as possible.
Example: Calculating D in the User Component
Metrics in Component User:
The value of A is 0.5
The value of I is 0.25
Therefore: $D= \left|0.5+0.25-1\right|$ = $\left|0.75-1\right|$ = 0.25
DInComponents
Example: User Component Tracking
We can apply control limits when analyzing the versions of a component and its Main Sequence Distance metrics. For example, let's imagine that the User component has several versions, as shown in the image; in this case, we can notice that the control limit is exceeded in version 2.2, so it would be desirable to analyze this version.
DVersionesUser

Metrics are Referential

All the metrics presented are not absolute laws, they are simply references to be taken into account when analyzing the components of an architecture. Also, all the examples presented are merely illustrative, as they should include many more software elements.

⚠️ **GitHub.com Fallback** ⚠️