How does Protected Variations relate to the Open/Closed Principle, the Dependency Inversion Principle, and Parnas's information hiding? Is it the same idea restated?
answer
- PV = where; DIP = how; OCP = did it work
- Parnas 1972 → Meyer OCP → Cockburn 1996 → Larman
- hide the decision, not the field
- client owns the abstraction (DIP clause)
- closed against *which* axis?
basics
~20 sThey aim at the same goal from different angles. Protected Variations is the general statement — wrap predicted change behind a stable interface. Open/Closed, Dependency Inversion and information hiding are specific, more prescriptive ways of doing exactly that.
solid answer
~50 sProtected Variations (PV) is the umbrella; the others are instances. **Information hiding** (Parnas, 1972) says modularise around the *decisions most likely to change* and hide each behind a module interface — PV's "predict, then wrap", stated for module decomposition. **Open/Closed** (Meyer) says a module should be open for extension but closed for modification — that is the *desired outcome* of successful protection: new variants arrive as new code, existing clients stay untouched. **Dependency Inversion** prescribes the *mechanism*: high-level policy and low-level detail both depend on an abstraction, and the abstraction is owned by the policy side, so a volatile detail cannot drag policy along with it. Alistair Cockburn's 1996 article explicitly frames Open/Closed and information hiding as the same underlying idea, and Larman adopted PV as the generalisation. Practically: PV tells you *where* to protect; DIP tells you *how* to wire it; OCP tells you whether it worked.
go deeper
Say that all four push change into one place behind a boundary, and give the concrete OCP form: add a new implementation instead of editing a switch statement.
Map each principle to the question it answers — where to protect (PV), how to decompose (information hiding), how to wire (DIP), how to verify (OCP).
Add the ownership subtlety of DIP (the client defines the abstraction) and the fact that closure is always relative to a named axis of change; give a case where an interface exists but nothing was actually protected.
Place them historically (Parnas → Meyer → Cockburn → Larman) and argue about cost: protection is an option purchase, and blanket application of OCP/DIP produces indirection without protection.
## Definitions before comparison - **Protected Variations (PV)** — GRASP principle: *identify points of predicted variation or instability; assign responsibilities to create a stable interface around them.* - **Information hiding** — David Parnas, *"On the Criteria To Be Used in Decomposing Systems into Modules"* (1972): each module should hide one **design decision** that is likely to change; the module interface reveals as little as possible about that decision. Crucially, Parnas argued you should decompose by *likely-to-change decisions*, **not** by processing steps in a flowchart. - **Open/Closed Principle (OCP)** — Bertrand Meyer: *a module should be open for extension, closed for modification.* You should be able to add behaviour without editing the module's existing source. (Robert Martin's later polymorphic reading: extend by adding new implementations of an abstraction.) - **Dependency Inversion Principle (DIP)** — Robert Martin: (a) high-level modules should not depend on low-level modules — both depend on abstractions; (b) abstractions should not depend on details — details depend on abstractions. ## The relationship, precisely Think of four different questions about the same act of design: | Principle | The question it answers | |---|---| | **PV** | *Where* should I put protection? → at predicted points of variation/instability | | **Information hiding** | *What* should a module be organised around? → one changeable decision, hidden | | **DIP** | *How* do I wire it so the dependency arrow points the safe way? → both sides depend on an abstraction owned by the policy side | | **OCP** | *How do I know it worked?* → new behaviour arrives as new code; existing modules aren't edited | Cockburn's 1996 IEEE Software article *"Protected Variation: The Importance of Being Closed"* argues explicitly that OCP and information hiding are two expressions of one principle, and proposes "protected variation" as the name for it. Larman then folded that name into GRASP. So the honest interview answer is: **they are not independent principles competing for your attention; they are one idea at different levels of abstraction and prescription.** ## Where they genuinely differ 1. **Scope.** Information hiding is about *module decomposition* (what belongs together). DIP is about *dependency direction* between layers. PV is stated for objects, subsystems **and** whole systems — including protecting against variation in a third-party vendor or a wire format. 2. **Prescriptiveness.** DIP names a concrete structural move (invert the arrow; the abstraction lives with the client/policy, not the provider). PV names none — polymorphism, a config table, a lookup service, an interpreter, or simply choosing a standard format all satisfy it. 3. **Mechanism vs. property.** OCP describes a *property* a module has or lacks. PV and DIP describe *actions* you take. 4. **DIP's ownership clause.** The subtle part of DIP that PV doesn't say out loud: it is not enough for an interface to exist — the *client side* should own/define it. If the volatile provider ships the interface, a provider change still churns the interface, and the protection evaporates. This is why an anti-corruption layer defines its *own* vocabulary rather than re-exporting the vendor's SDK types. ## Worked illustration A pricing engine must call a tax service. - **PV** identifies tax rules as a predicted variation point (regulation changes, new jurisdictions, a vendor swap). - **Information hiding** says one module owns the "how tax is computed" decision and exposes nothing about jurisdiction tables or vendor payloads. - **DIP** says the pricing (high-level policy) declares `TaxCalculator` in its own terms; the vendor adapter implements it. The compile-time dependency now points from vendor → policy, the reverse of the runtime call. - **OCP** is the outcome: adding *Canada* means adding `CanadianTaxCalculator`; the pricing engine's source is not reopened. ## Common traps - **An interface is not automatically DIP.** If the interface merely mirrors the vendor SDK's method names, types and error codes, the dependency was *not* inverted — it was renamed. - **OCP has a direction.** You are closed against *some specific axis* of change, and open along it. No module is closed against all change; asking "closed against what?" is the mark of a senior answer. - **Information hiding ≠ private fields.** Hiding a *field* is encapsulation. Hiding a *decision* (which algorithm, which format, which vendor, which storage layout) is the Parnas idea PV builds on. ## Summary line PV is the *why and where*; information hiding is the *decomposition rule*; DIP is the *wiring rule*; OCP is the *acceptance test*.
- If an interface exists between the policy and the vendor, is the Dependency Inversion Principle satisfied?Not necessarily. DIP also requires that the abstraction not depend on details — in practice, that the client/policy side define the interface in its own vocabulary. An interface auto-derived from a vendor SDK still changes whenever the vendor changes, so the protection is nominal.
- Can code satisfy the Open/Closed Principle without any interfaces or inheritance?Yes. Closure can come from data-driven design (rules in a table), from passing behaviour as a function/callback, from plugin registration, or from an interpreter that reads a rules script. OCP describes the property; polymorphism is only the most familiar means to it.
Four people describing one door in a wall. PV: "put the door where people will actually need to pass." Information hiding: "whatever is behind it stays out of sight." DIP: "the frame belongs to the wall, not to whatever room gets built behind it." OCP: "you can add rooms without knocking holes in the wall."
saying these in an interview costs you the question
- Presenting PV, OCP, DIP and information hiding as four unrelated principles you can apply independently, rather than one idea at different levels.
- Saying "OCP means never modify existing code" — closure is always relative to a chosen axis of change; nothing is closed against everything.
- Equating DIP with "use dependency injection". DI is a wiring technique; DIP is a statement about which side owns the abstraction and which way the source dependency points.
- Reducing information hiding to "make fields private" instead of hiding a design decision that is likely to change.
- Claiming PV is a modern/agile invention — the lineage runs Parnas (1972) → Meyer's OCP → Cockburn (1996) → Larman's GRASP.