Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add principles about component cohesion and coupling #11

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -558,3 +558,145 @@ The law is originating from the book 'The Cathedral and the Bazaar' by Eric S. R
Resources

- [Linus's law in Wikipedia](https://en.wikipedia.org/wiki/Linus%27s_law)

## Reuse Release Equivalence Principle

> The granule of reuse is the granule of release

Reuse of software components is enhanced by tracking them through a release process and assigning them release numbers.

Why

- There is a need to know what changes new releases will bring in order to know when to integrate them.

How

- Group classes and modules that belong to the same components into cohesive groups.
- Release groups of classes and modules together.

Resources

- Clean Architecture by Robert C. Martin, Chapter 13 Component Cohesion, The Reuse/Release Equivalence Principle
- [Reuse Release Equivalence Principle](https://wiki.c2.com/?ReuseReleaseEquivalencePrinciple)

## 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 have only one reason to change.

This is a restatement of the Single Responsibility Principle at the component level. It is also related to the Open Closed Principle because it focuses on the strategy of closing components from changes.

Why

- When changes are required, they should be confined to the minimal number of components instead of being distributed across many components.

How

- Group together in the same components all the classes that are likely to change for the same reasons.

Resources

- Clean Architecture by Robert C. Martin, Chapter 13 Component Cohesion, The Common Closure Principle
- [Common Closure Principle](https://wiki.c2.com/?CommonClosurePrinciple)

Related

- [Single Responsibility Principle](#single-responsibility-principle)
- [Open Closed Principle](https://en.wikipedia.org/wiki/Open/closed_principle)

## Common Reuse Principle

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

Classes and modules that tend to be reused together should be part of the same component.

This principle can be viewed as a generalization of the Interface Segregation Principle.

Why

- When a component depends on another one, each time the latter is modified, the former needs to be recompiled, revalidated, and redeployed. This applies even when the using component doesn't require any changes or depends on a single class of the used component.

How

- Put classes that depend solely on each other into the same component, and avoid depending on classes from different components.

Resources

- Clean Architecture by Robert C. Martin, Chapter 13 Component Cohesion, The Common Reuse Principle
- [Common Reuse Principle](https://wiki.c2.com/?CommonReusePrinciple)

Related

- [Interface Segregation Principle](#interface-segregation-principle)

## Acyclic Dependencies Principle

> Allow no cycles in the component dependency graph.

The dependency structure of components can be viewed as a graph, with components as the nodes and dependency relationships as the directed edges. This graph should not have any cycles, meaning there should be no cyclic dependencies among software components.

Why

- Elements in a cycle represent a component that requires all its elements to be developed, validated, tested, and deployed together.
- In the presence of a cycle, it becomes difficult to isolate components, making unit testing and releasing difficult.
- Cyclic dependencies may require knowing the order in which the components must be built.

How

- Apply the Dependency Inversion Principle: replace the dependency of a high-level component on a low-level one with an abstraction that both of them depend on.
- When a cycle occurs, break the components involved creating new components.

Resources

- Clean Architecture by Robert C. Martin, Chapter 14 Component Coupling, The Acyclic Dependencies Principle
- [Acyclic dependencies principle - Wikipedia](https://en.wikipedia.org/wiki/Acyclic_dependencies_principle)
- [Acyclic Dependencies Principle (c2.com)](https://wiki.c2.com/?AcyclicDependenciesPrinciple)

Related

- [Dependency inversion principle - Wikipedia](https://en.wikipedia.org/wiki/Dependency_inversion_principle)

## Stable Dependencies Principle

> Depend in the direction of stability

Ensure that components that are intended to be easy to change are not depended on by components that are harder to change.

The instability of a component, where stability is defined as the amount of work required to change it, should be greater than the instability of the components it depends on.

Why

- In designing a system, some components should be easy to change and others should not. The latter are the ones with higher instability, while the former are the most stable.

How

- Measure the instability $I$ of a component $C$ with this formula: $I = DO \div (DI + DO)$ where $DI$ consists in the number of components that depend on $C$, and $DO$ is the number of components that $C$ depends on.

Resources

- Clean Architecture by Robert C. Martin, Chapter 14 Component Coupling, The Stable Dependencies Principle
- [Stable Dependencies Principle (c2.com)](https://wiki.c2.com/?StableDependenciesPrinciple)

## Stable Abstractions Principle

> A component should be as abstract as it is stable.

Stable components should also be abstract, so that their stability does not prevent them from being extended. At the same time, unstable components should be concrete, making it easy to change them.

Why

- Components that are unlikely to change are highly stable. However, their lack of instability makes it even harder to extend them. To guarantee flexibility, these components can be extended without requiring modification by leveraging abstract classes and interfaces.

How

- Keep track of abstractness $A$ of a component, which is calculated as follows: $A = N_{a} \div N_{c}$ where $N_{c}$ is the number of classes in the component, and $N_{a}$ is the number of abstract classes and interfaces in the component.
- Avoid creating highly stable and concrete component because they cannot be extended; they are not abstract and it is difficult to change due to their stability.
- Do not make components too unstable and abstract, because they may become useless.

Resources

- Clean Architecture by Robert C. Martin, Chapter 14 Component Coupling, The Stable Abstractions Principle
- [Stable Abstractions Principle (c2.com)](https://wiki.c2.com/?StableAbstractionsPrinciple)