What does the Common Closure Principle (CCP) of component design state, and what problem does it prevent?
answer
- same reasons + same times -> one component
- SRP at component granularity
- closure = OCP fallback: concentrate the change
- minimize components touched/redeployed per change
- inclusive force; opposes CRP
basics
~20 sCCP says: put into one component the classes that change for the same reasons and at the same times. Then a typical change touches one component instead of many, so you rebuild, retest and redeploy less.
solid answer
~50 sCCP is one of the three component-cohesion principles (with REP and CRP). It states: gather into a component those classes that change for the same reasons and at the same times; separate classes that change for different reasons or at different times. It is the Single Responsibility Principle raised from the class level to the component level - a component should have one reason to change. The payoff is operational: if a requirement change is confined to one component, only that component must be recompiled, revalidated, redeployed, and re-released. It prevents shotgun surgery, where a single business change forces edits scattered across many packages and a lockstep release of all of them. The word closure comes from the Open-Closed Principle: where you cannot make code closed against a change, at least concentrate that change into one component so the blast radius is one deployable unit.
go deeper
State the rule plainly - classes that change for the same reasons at the same times go in one component - and give the benefit: one change, one component to rebuild and redeploy.
Add that CCP is SRP at component scale and that 'closure' comes from OCP; connect it to package-by-feature versus package-by-layer and to reducing shotgun surgery.
Discuss the tension with CRP and REP, note that CCP is a dynamic property requiring boundary refactoring, and mention using version-control co-change data as evidence.
Frame CCP as the driver of deployable/service boundaries and team ownership: a change requiring lockstep releases of several services is a CCP violation at architecture scale, and boundaries should track how the business actually changes.
## Define the terms first - **Class**: the smallest unit of behaviour plus data. In non-OO languages, read it as module/file/function group. - **Component**: the smallest unit of **deployment and release** - a jar, DLL, wheel, gem, npm package, or at minimum a versioned source package/directory that ships as a whole. Bigger than a class, smaller than the system. - **Cohesion principles**: rules about *which classes belong inside the same component*. There are three classic ones: - **REP** (Reuse/Release Equivalence Principle): the granule of reuse is the granule of release - things reused together must be released and versioned together. - **CCP** (Common Closure Principle): the subject of this question. - **CRP** (Common Reuse Principle): don't force users of a component to depend on things they don't use; classes that are not reused together should not be in the same component. ## The statement > 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. Two clauses matter, and juniors usually quote only the first: 1. **same reasons** - the same *axis of change*: the same stakeholder, the same regulation, the same UI redesign, the same external API version. 2. **same times** - the same *cadence*: things that are edited together in the same commit/release, even if the abstract reason is arguably different. ## Why it is called *closure* The **Open-Closed Principle (OCP)** says software should be open for extension but closed for modification - a change should ideally be absorbed by adding code rather than editing existing code. In practice, no design is closed against *every* possible change. CCP is the pragmatic fallback: for the changes you could not close against, arrange the code so that all the edits fall **inside one component**. So CCP = "if a change must happen, make it *closed within* a single component." ## Why it is SRP at component scale The **Single Responsibility Principle** says a class should have one reason to change, i.e. it should answer to one actor/stakeholder. CCP applies exactly the same rule where the unit is a component instead of a class. A component that changes when Accounting changes rules **and** when the mobile team redesigns a screen has two reasons to change - it violates component-level SRP. ## What it buys you - **Fewer components touched per change** - less to recompile, retest, review, version-bump, and redeploy. - **Smaller revalidation surface** - integration tests, sign-off, and release notes shrink. - **Less coordination** - one team can complete a change without cross-team lockstep releases. - **Simpler dependency management** - fewer cascading version bumps up the dependency graph. ## What it costs / trade-offs - CCP is **inclusive** (it pulls classes together, making components larger). CRP is **exclusive** (it pushes classes apart to avoid forcing unnecessary dependencies on consumers). They pull in opposite directions and must be balanced. - Over-applying CCP produces a few large components: consumers get more code than they need, and unrelated releases churn the same artifact. - CCP is about **maintainability/developability**, not reuse. Optimising purely for CCP can hurt reusability, which is REP/CRP territory. ## Edge cases and nuance - **The grouping is not static.** The axes of change shift as the product evolves; a partition that satisfied CCP two years ago may not now. CCP is a *dynamic* property that should be revisited, and refactoring component boundaries is a normal maintenance activity. - **"Same reason" is empirical, not philosophical.** You can measure it: version-control history shows which files habitually change in the same commit (temporal/logical coupling). Files that co-change constantly but live in different components are CCP smells. - **It is about change, not about similarity of name or type.** Putting all DTOs in one package because they are all DTOs is a type-based grouping, not a change-based one. - CCP is closely related to Conway's Law in practice: if a component is owned by one team and changes with that team's roadmap, CCP and the org chart reinforce each other. ## Quick recognition test Take the last 10 merged changes. For each, count how many components were edited. If the median is 1, CCP is holding. If it is 4-5 and the same combination of components keeps appearing, your boundaries are cutting *across* the real axes of change.
- How is CCP different from the Single Responsibility Principle?They are the same idea at different granularities. SRP says a class should have one reason to change; CCP says a component should have one reason to change. CCP additionally emphasises the temporal clause - classes that change at the same times belong together even if you'd argue the reasons differ.
- Where does the word 'closure' in Common Closure Principle come from?From the Open-Closed Principle. Since you cannot close a design against every possible change, CCP asks you to make the component the unit within which unavoidable changes are contained - the change is 'closed' inside one component.
- Does CCP mean bigger components are better?No. CCP alone pushes toward bigger components, but the Common Reuse Principle pushes back by splitting out classes that consumers don't use together. A good partition balances the two rather than maximising either.
Emergency kit packing. You don't sort by material (all metal in one box, all plastic in another) - you pack by the event: the fire kit, the flood kit, the first-aid kit. When a flood happens you grab one box. CCP packs code by the event that will force you to open the box.
saying these in an interview costs you the question
- Reciting only 'classes that change together' and dropping the 'for the same reasons' half, which turns CCP into a coincidence detector
- Claiming CCP is about grouping technically similar classes (all controllers, all DTOs) rather than co-changing ones
- Saying CCP means components should be as large as possible - ignoring the opposing pull of CRP
- Treating CCP as a one-time, permanent partition rather than something that must be revisited as change axes shift
- Confusing CCP with CRP: CRP is about not forcing unused dependencies on consumers, not about change frequency