How does the GRASP Indirection principle differ from the GRASP principles Pure Fabrication and Protected Variations, given that all three often produce the same extra class?
answer
- PV = why, Indirection = how, Fabrication = what kind of class
- PV names the axis of change
- Fabrication = invented, non-domain class
- Mediator between peers = indirection, no PV
- ClearingHouse = indirection by a real domain object
basics
~20 sThey describe different reasons for the same extra class. Protected Variations is the goal (shield callers from change). Indirection is the mechanism (put an object in between). Pure Fabrication is the licence to invent a non-domain class to do it.
solid answer
~50 sAll three GRASP principles frequently point at one artifact — e.g. a `PaymentGateway` — but they answer different questions. **Protected Variations** asks *why*: identify a predicted point of instability (a vendor, a protocol, a format) and wrap it behind a stable interface so change does not ripple. It is the goal/policy. **Indirection** asks *how*: introduce an intermediate object so the two parties never touch. It is the structural mechanism, and it is also used for reasons other than variation — breaking cycles, decoupling peers, adding a cross-cutting hook. **Pure Fabrication** asks *what kind of class*: it permits inventing a class that has no counterpart in the domain vocabulary (`Repository`, `Mapper`, `Coordinator`) to preserve cohesion and keep domain objects free of persistence/transport concerns. In practice: Protected Variations motivates it, Indirection shapes it, Pure Fabrication justifies its non-domain name. Indirection objects are usually — but not always — pure fabrications.
go deeper
Say the one-liner: Protected Variations = why, Indirection = how, Pure Fabrication = the invented class. One example (repository) is enough.
Walk through the repository example naming all three, and mention that Pure Fabrication exists to rescue cohesion when Information Expert would push persistence into the entity.
Show the separating cases — a mediator with no predicted variation, a domain-real intermediary that is not a fabrication, and Protected Variations achieved via configuration or polymorphism with no mediator at all.
Use the distinction to police architecture: demand a named variation axis before approving a new layer, and recognize when Protected Variations is better bought with data-driven design or deployment boundaries than with more classes.
## Setting the scene GRASP (*General Responsibility Assignment Software Patterns*) contains nine principles for deciding which object gets which responsibility. Three of them — **Indirection**, **Pure Fabrication**, and **Protected Variations** — are the "advanced" trio, and in an interview they are routinely conflated because applying any of them tends to produce an extra class in the middle. The distinction is one of *question answered*, not of resulting diagram. ### Protected Variations — the WHY (policy / goal) > *Identify points of predicted variation or instability; assign responsibilities to create a stable interface around them.* Key words: **predicted**, **stable interface**. You must be able to name the axis: "the payment vendor will change", "we will support both Postgres and an in-memory store in tests", "the file format has versions". Protected Variations is essentially GRASP's statement of the Open–Closed Principle and of information hiding (Parnas: modularize around *decisions likely to change*). It is a **goal**. It does not tell you what code to write. ### Indirection — the HOW (mechanism / structure) > *To avoid direct coupling between two components, assign the responsibility of mediating between them to an intermediate object.* Key words: **between two components**. Indirection is structural. It is the most common *implementation technique* for Protected Variations — but it has other motivations that have nothing to do with predicted change: - **Breaking a dependency cycle**: A ↔ B becomes A → M ← B. - **Reducing an N×N mesh**: eight UI widgets that each know the other seven become eight widgets that each know one mediator (the Mediator pattern). - **Providing a hook point**: metrics, retries, authorization, caching, transaction demarcation applied once, in the middle. - **Enforcing a boundary for organizational reasons**: two teams agree on a contract object so they can deploy independently. So: *every Protected Variations solution built from a wrapper is an indirection, but not every indirection is a Protected Variations.* ### Pure Fabrication — the WHAT KIND (nature of the class) > *Assign a highly cohesive set of responsibilities to an artificial class that does not represent a concept in the problem domain, in order to support low coupling and high cohesion.* Key word: **does not represent a domain concept**. The domain of an online shop contains `Order`, `Customer`, `Invoice`. It does not contain `OrderRepository`, `OrderMapper`, `OrderController`, `PaymentGateway`, or `CheckoutCoordinator` — those are invented. Pure Fabrication is the explicit permission to invent them, instead of forcing `Order.saveToDatabase()` onto a domain object (which would be justified by a naive reading of Information Expert and would couple the domain to SQL/JDBC/ORM). Pure Fabrication is about **preserving cohesion of domain objects** and giving a home to mechanism-flavoured work. ## Putting them together on one example Requirement: an order must be persisted, and the storage technology may change. | Question | Principle | Answer for this example | |---|---|---| | Why are we adding anything at all? | **Protected Variations** | Storage technology is a predicted variation point; callers must not see it. | | What shape does the solution take? | **Indirection** | `OrderService` never calls the ORM/SQL client; it calls `OrderRepository`, which mediates. | | Is it legitimate for `OrderRepository` to exist even though "repository" is not a business word? | **Pure Fabrication** | Yes — it is an invented, highly cohesive class that keeps persistence out of `Order`. | | Why not put `save()` on `Order` itself, which knows its own data? | **Information Expert taken too literally** | Because it would drag persistence coupling into the domain and wreck `Order`'s cohesion. | ## Cases that separate them cleanly **Indirection without Protected Variations.** A `ChatRoom` mediator between `Participant` objects. There is no predicted variation being shielded; the point is to collapse a peer-to-peer mesh into a hub so participants don't reference each other. **Indirection without Pure Fabrication.** The mediating object is itself a genuine domain concept. In a trading system, an `Exchange` or `ClearingHouse` sits between `Buyer` and `Seller` and is a real business entity — indirection realized by a domain object, not a fabricated one. Likewise a `Broker` in an insurance domain. **Pure Fabrication without Indirection.** An invented `TaxCalculationPolicy` or `PricingEngine` that does not mediate between two parties at all — it simply gathers cohesive algorithmic work that fits no domain entity. **Protected Variations without a new class.** Sometimes the variation is protected by data-driven design (a lookup table, a config file, feature flags), by late binding in the language, or by a plug-in registry — no bespoke mediator class needed. ## Interview-grade summary sentence > Protected Variations names the *risk*; Indirection is the *shape of the fix*; Pure Fabrication is the *permission to invent the class that implements it*. The three collapse onto one artifact in the common case, which is exactly why you should be able to pull them apart on demand. ## Why the distinction matters practically If you cannot separate them, you produce two failure modes: 1. **Indirection with no Protected Variations rationale** — layers added "because clean architecture", with no named axis of change. Cost paid, benefit imagined. 2. **Protected Variations pursued by non-indirection means being overlooked** — you reflexively add a wrapper where configuration, a strategy passed as a parameter, or plain polymorphism would have been cheaper.
- Give an indirection that is NOT a pure fabrication.A domain-real intermediary: a `ClearingHouse` between `Buyer` and `Seller`, an `Escrow` between payer and payee, an `Agent` between client and provider. The mediating object exists in the business vocabulary, so it is not invented.
- Why doesn't Information Expert simply tell us to put save() on the entity that owns the data?Because Information Expert optimizes for 'who has the data' and, applied blindly to mechanism-flavoured work such as persistence or serialization, it destroys cohesion and couples domain objects to infrastructure. Pure Fabrication is the explicit escape hatch for exactly that situation.
- Can Protected Variations be achieved without introducing any indirection object?Yes: data-driven configuration, a strategy function passed as a parameter, a plug-in registry resolved by the runtime, or simply choosing a language mechanism (virtual dispatch, duck typing) can shield callers from variation without a bespoke mediator class.
saying these in an interview costs you the question
- "Indirection and Pure Fabrication are the same principle" — one is about a mediating position, the other about a class not existing in the domain vocabulary.
- "Protected Variations means wrap everything, because anything could change" — PV requires a *predicted*, named variation point; speculative wrapping is the anti-pattern it is often mistaken for.
- Assuming an indirection object is always artificial — mediators like ClearingHouse, Escrow, or Broker are genuine domain concepts.
- Assuming Pure Fabrication always mediates — a fabricated PricingEngine can hold cohesive algorithm code without sitting between two parties.
- Treating GRASP principles as mutually exclusive alternatives rather than complementary lenses that often justify one artifact together.