skip to content

How do the Common Closure Principle, the Single Responsibility Principle, and the Open-Closed Principle relate to each other?

level: middleimportance: nice to knowfreq 18%

answer

  1. SRP:class :: CCP:component
  2. 'closure' borrowed from OCP
  3. OCP first (extend), CCP as fallback (contain)
  4. CCP adds the 'same times' clause
  5. ISP:class :: CRP:component

basics

~20 s

SRP: a class has one reason to change. CCP is the same idea for components: a component has one reason to change. OCP says prefer extending over modifying; where you can't, CCP keeps the unavoidable modification inside one component.

solid answer

~50 s

The three form a chain about *where change lands*. SRP operates on classes: a class should answer to one actor, so it has one reason to change. CCP is SRP restated with the component - the deployable/releasable unit - as the subject, adding a temporal clause: classes that change at the same times belong together. OCP is the aspiration above both: design so that new behaviour arrives by adding code (extension) rather than editing existing code (modification), typically via polymorphism or a plug-in seam. Because no design is closed against every possible change, CCP acts as OCP's fallback - hence the word 'closure'. If you cannot avoid modification, at least make the modification *closed within one component*, so only that component is rebuilt, retested, and redeployed. In practice you apply OCP against the changes you can predict, and CCP to contain the ones you cannot.

go deeper

for a junior

Say SRP is one reason to change for a class and CCP is the same for a component, and that OCP prefers adding new code to editing old code.

for a middle

Explain that 'closure' comes from OCP and CCP is its fallback when you cannot close against a change, and note CCP's extra 'same times' clause.

for a senior

Give the granularity table, the SRP-actor framing, the SRP/CCP and ISP/CRP symmetry, and warn against speculative abstraction when chasing OCP.

for a principal

Position them as a policy: close against the variation you can genuinely predict, contain the rest by boundary placement, and treat both as revisitable as the actual axes of change are revealed by history.

## The three statements - **SRP - Single Responsibility Principle**: a class should have one, and only one, reason to change. The sharper modern phrasing: a module should be responsible to one and only one *actor* (one group of stakeholders that requests changes). Two actors requesting changes to the same class means their changes collide. - **OCP - Open-Closed Principle**: software entities should be open for extension but closed for modification. New behaviour should be addable without editing the existing, already-tested code - normally by depending on an abstraction and adding a new implementation behind it. - **CCP - Common Closure Principle**: gather into a component the classes that change for the same reasons and at the same times. Separate those that change for different reasons at different times. ## How they line up | Principle | Unit | Question it answers | |---|---|---| | SRP | class | How many reasons may this class have to change? (one) | | CCP | component | How many reasons may this component have to change? (one) | | OCP | any | Can the change be absorbed by adding rather than editing? | SRP -> CCP is a **change of granularity**: same idea, bigger unit. That is why CCP is often introduced as 'SRP for components'. CCP adds one thing SRP does not stress: **timing**. Two classes may arguably change for different reasons, but if they invariably change in the same release, CCP puts them together anyway, because the operational cost is what CCP is optimising. OCP -> CCP is a **fallback relationship**. The word *closure* is taken directly from OCP. Ideally a component is closed against a change (no edit needed). Reality: you can only be closed against *anticipated* kinds of change, and abstracting against every possible change is over-engineering. So CCP says: for the changes you did not or could not close against, ensure the edits are contained in one component - closed *within* a boundary rather than closed *out* entirely. ## A worked chain Suppose tax rules change every quarter. 1. **OCP attempt**: define a `TaxRule` abstraction so a new jurisdiction's rule is a new implementation - added, not edited. Change absorbed by extension. 2. **What OCP cannot close**: the shape of the abstraction itself. If the tax authority introduces a concept the interface cannot express, you must modify. 3. **CCP then applies**: keep the rule implementations, the rule interface, and their configuration in **one** component, so that unavoidable modification means one component rebuilt and redeployed, not five. 4. **SRP inside it**: within that component, no single class should serve both the tax-authority actor and, say, the reporting actor. ## Common confusions - **SRP is not 'a class does one thing'.** It is about *one reason to change / one actor*. A class can perform several coordinated steps for one actor and still satisfy SRP. - **OCP does not forbid ever editing code.** It says prefer designs where common, anticipated variation is additive. Blanket abstraction 'in case' is speculative generality. - **CCP is not 'put everything together'.** The Common Reuse Principle counterbalances it by ejecting classes consumers don't use. - **CCP is not a SOLID principle.** SOLID (SRP, OCP, LSP, ISP, DIP) governs classes; the component principles are a separate set - cohesion (REP, CCP, CRP) and coupling (ADP, SDP, SAP). Mixing the two families up is a common interview slip. ## Cousins worth naming The class-level principles have component-level analogues: SRP ~ CCP, and ISP (don't force clients to depend on methods they don't use) ~ CRP (don't force consumers to depend on classes they don't use). Noticing that symmetry is a strong signal in an interview.

  • Is CCP part of SOLID?
    No. SOLID (SRP, OCP, LSP, ISP, DIP) applies at class level. CCP belongs to the component principles: cohesion (REP, CCP, CRP) and coupling (ADP, SDP, SAP). CCP is the component-level analogue of SRP, and CRP is the component-level analogue of ISP.
  • If OCP were applied perfectly, would CCP become unnecessary?
    In theory, but perfect closure is impossible - you can only close against anticipated axes of change, and abstracting against every conceivable one is speculative over-engineering. CCP exists precisely because some modification is always unavoidable; it bounds where that modification lands.
  • What does CCP emphasise that SRP does not?
    Timing. SRP focuses on reasons to change (actors). CCP adds 'at the same times' - classes that always change in the same release belong together even if you'd argue the reasons differ, because CCP optimises the concrete cost of rebuild, retest, and redeploy.

OCP is waterproofing the roof so rain never gets in. CCP is admitting some rain always gets in, and making sure it drips into one bucket rather than across the whole floor.

saying these in an interview costs you the question

  • Listing CCP as one of the SOLID principles
  • Stating SRP as 'a class should do only one thing' rather than 'one reason to change / one actor'
  • Claiming OCP means never modifying existing code under any circumstances
  • Missing the temporal clause of CCP and treating it as a pure restatement of SRP
  • Not knowing that CRP is the component-level analogue of ISP, the parallel case to CCP/SRP

context