How does the Common Reuse Principle (CRP) relate to the Interface Segregation Principle (ISP), and how is it different from the Common Closure Principle (CCP)?
answer
- CRP = ISP for components
- CCP = SRP for components
- CCP: change together (maintainer). CRP: used together (consumer)
- CCP groups, CRP splits — they fight
- ISP splits interfaces; CRP splits shipped artifacts
basics
~20 sCRP is ISP one level up: ISP says don't make a client depend on methods it doesn't use; CRP says don't make it depend on classes it doesn't use. CCP is different — it groups classes that change together, not classes used together.
solid answer
~50 sISP and CRP are the same idea at two granularities. ISP operates on interfaces: split a fat interface so a client isn't coupled to methods it never calls. CRP operates on components (units of release): split a fat package so a consumer isn't coupled to classes it never uses. Both are consumer-facing, and both are motivated by the fact that unnecessary coupling forces unnecessary recompilation, revalidation and redeployment. CCP is cohesion along a different axis and for a different audience: it says classes that change for the same reasons, at the same times, belong in one component, so that a given change lands in as few components as possible. CCP serves the maintainer (fewer artifacts to rebuild and release per change); CRP serves the consumer (fewer irrelevant releases to absorb). They frequently conflict: CCP wants to pull classes in, CRP wants to push unrelated ones out, and the architect chooses the balance.
go deeper
Get the two mappings right: CRP↔ISP (usage) and CCP↔SRP (change). One example each is enough.
Explain the shared mechanism (a dependency edge propagates change/release), and give one concrete case where CCP and CRP disagree.
Discuss resolution strategy: use real consumer data and change frequency to pick a side, and note that the right answer moves over a project's lifetime.
Frame it as an economic trade — maintainer release cost versus consumer absorption cost across an organisation — and describe the governance (ownership, deprecation policy, artifact-count budget) that keeps the choice revisable.
## The three component-cohesion principles Robert C. Martin defines three principles about *which classes belong in which component*, where a **component** is a unit of deployment/release (jar, npm package, wheel, DLL): | Principle | Statement | Whose pain does it address? | Direction | |---|---|---|---| | **REP** — Reuse/Release Equivalence | The granule of reuse is the granule of release: a component must be versioned, released and documented as a coherent whole. | Consumer (can I depend on this at all?) | groups | | **CCP** — Common Closure | Gather into a component the classes that change for the same reasons and at the same times. | Maintainer (how many artifacts must I touch and release for one change?) | groups | | **CRP** — Common Reuse | Don't force consumers of a component to depend on things they don't need. | Consumer (what am I dragged into?) | splits | CCP is the Single Responsibility Principle restated for components ("one reason to change"). CRP is the Interface Segregation Principle restated for components. ## CRP as ISP scaled up **ISP (class/interface level):** "Clients should not be forced to depend upon interfaces they do not use." The canonical smell is a fat interface where an implementer must stub out methods it has no meaning for, and every client recompiles when any method signature changes. **CRP (component level):** "Clients should not be forced to depend upon *classes* they do not use." The canonical smell is a grab-bag package where a consumer inherits unrelated subsystems, their transitive dependencies, and their release cadence. The shared mechanism is the same in both cases: **a dependency edge propagates change.** At interface level the propagation is recompilation and re-linking; at component level it is re-integration, re-testing, re-certification and redeployment, plus dependency-closure effects (version conflicts, CVEs, artifact size). Some authors summarise CRP simply as "ISP for packages", and Martin himself writes that CRP is the generic version of ISP: ISP advises against depending on classes with methods you don't use, CRP advises against depending on components with classes you don't use. ## CRP vs CCP: two different axes of cohesion The critical distinction: - **CCP asks: do these classes change together?** (temporal/causal cohesion, maintainer's view). If a new tax rule always touches `TaxRateTable`, `TaxCalculator` and `TaxReport`, CCP says put them in one component so one change touches one artifact. - **CRP asks: are these classes used together?** (usage cohesion, consumer's view). If half your consumers use only `TaxCalculator` and never the reporting classes, CRP says the reporting classes are dragging those consumers along. These can point the same way (things that change together are often used together) but frequently do not. Two examples of conflict: 1. A component containing an entity and its admin-only reporting/export code: they change together when the schema changes (CCP: keep together), but 90% of consumers only read the entity (CRP: split). 2. A component gathering everything owned by one team (CCP-flavoured, minimises release fan-out for that team) whose consumers each use a different slice (CRP violation). When they conflict, you are choosing whose cost to pay: the maintainer's (more artifacts to release per change) or the consumer's (more irrelevant releases to absorb). Early in a project, with few external consumers and rapid change, CCP wins. As a library matures and the consumer count grows, CRP's cost dominates and you split. ## Where the analogy with ISP stops - ISP can often be satisfied *without any physical repackaging* — you split the interface and the implementation may still live in one artifact. CRP by definition requires changing what is shipped; a purely logical split (subpackages inside the same jar) does not satisfy CRP, because the consumer still takes the whole artifact. - ISP's cost of over-application is a proliferation of tiny interfaces (annoying but cheap). CRP's cost of over-application is a proliferation of published artifacts, which is expensive: versioning, release coordination, dependency-graph complexity, CI pipelines. - ISP has no direct antagonist principle; CRP is explicitly in tension with REP and CCP. ## Quick recall table - SRP → classes; **CCP** → components (change axis) - ISP → interfaces; **CRP** → components (usage axis) - REP → the release/versioning precondition that makes either meaningful
- Give a concrete case where CCP and CRP give opposite advice, and say how you'd resolve it.An order entity plus its admin export/reporting code: they change together whenever the schema changes (CCP says one component), but the vast majority of consumers use only the entity and never the export code (CRP says split). Resolve by counting consumers and change frequency: if the export code changes rarely and consumers are numerous, split and accept the two-artifact release; if the pair churns constantly and there are few consumers, keep it together and revisit later.
- Does satisfying CRP by moving classes into separate sub-packages inside the same jar work?No. A component is a unit of release; consumers still take the whole jar, so they still inherit its releases, transitive dependencies and CVEs. A sub-package split is only useful as preparation for an actual artifact split.
- Which of the three cohesion principles is the 'exclusive' one, and why does that matter?CRP. REP and CCP are inclusive — they tell you what to put *in* a component and thus make components bigger. CRP is exclusive — it tells you what to keep *out*, making components smaller. Knowing this tells you which principle to invoke when a component is bloating versus fragmenting.
ISP is refusing a menu where ordering coffee obliges you to take the whole breakfast platter. CRP is refusing a supermarket that only sells one giant mixed crate — you wanted eggs, you're carrying home the fish too, and when the fish spoils the whole crate is recalled.
saying these in an interview costs you the question
- Saying CRP and CCP are "basically the same cohesion idea" — they are different axes (usage vs change) serving different audiences.
- Claiming CRP is satisfied by reorganising namespaces or folders without changing what is published.
- Saying CRP is the component version of SRP (it is ISP; SRP maps to CCP).
- Asserting the principles never conflict; the tension between them is the whole design problem.
- Applying ISP's cheapness intuition to CRP — splitting artifacts is far more expensive than splitting interfaces.