Component cohesion
Which classes belong in which components.
Three principles of component cohesion
- REP: reuse/release equivalence principle
- CCP: common closure principle
- CRP: common reuse principle
Reuse/Release equivalence principle
People who want to reuse software components cannot and will not unless they are tracked through a release process and given version numbers. Developers need to know when new releases are coming and what changes they will bring. It's not uncommon for developers to choose to stick with an old release instead. cough ramda 0.27 cough
From an architecture perspective this group of classes forms a cohesive group.
Another way of looking at it: classes and modules that are grouped together into a component should be releasable together.
Really this is weak advice that is more of a heuristic, it's hard to precisely explain what holds the classes and modules together into a single component. The weakness is compensated for by the other two principles which are much stronger.
Common closure principle
If classes change for the same reasons at the same times they belong in a component together. A component should not have multiple reasons to change.
Most of the time maintainability is more important than reusability. It is better for changes to be localised to a single component rather than spread out over the codebase. This also reduces the workload related to compiling and deploying changed components.
This is the component form of the SRP - gather things that change at the same time for the same reasons, separate things that change at different times or for different reasons. The CPP is also related to the open closed principle - the component is a closure.
Common reuse principle
Classes and modules that tend to be reused together belong in the same component. Usually classes form a single part of a reusable abstraction, e.g. a container and its iterators.
When a component uses another it creates a dependency, changes to the used component can affect the using component. Even if it only uses a small part of the other component, changes to the parts it doesn't use could cause recompilation, revalidation, and redeployment. Classes that are not tightly bound to each other should not be in the same component.
Like the interface segregation principle, but splitting components instead of hiding parts through an interface.
Don't depend on things you don't need
Tension diagram for component cohesion
REP and CCP specify what should be in components, make them larger.
- classes that are releasable together
- classes that change together
The CRP is exclusive, wants to make components smaller
- Classes that are not used together should be split
Early in development CCP is more important than REP because developability is more important than reuse. Projects tend to start on the right hand side and move left as reuse and maintainability become more of a concern. The component structure will evolve during the development based on maturity more than what it does.