GRASP tells you to evaluate High Cohesion and Low Coupling together on every responsibility assignment. Why can't you simply maximize one of them in isolation?
answer
- Cohesion looks inward, coupling looks outward — different axes
- Max cohesion alone → class explosion, more edges, shotgun surgery
- Max decoupling alone → self-sufficient God class / copy-paste
- Usually they agree; conflict appears past the natural seam
- Escape hatches: Pure Fabrication, Indirection, Protected Variations
basics
~20 sThey pull against each other. Splitting a class to make it more focused creates more classes that must talk to each other, raising coupling. Merging classes to cut dependencies makes each one do too much. You look for the balance point.
solid answer
~50 sCohesion is an *intra*-module property (how related the contents of one class are); coupling is an *inter*-module property (how much a class depends on others). Optimizing either alone degrades the other. Maximum cohesion taken literally means one responsibility per class: dozens of tiny types, long collaboration chains, heavy wiring, and more inter-class dependencies to track — high coupling and high cognitive load. Maximum decoupling taken literally means merging everything into one self-sufficient class with zero dependencies — the God class, with terrible cohesion. That is why GRASP applies them as a *pair of evaluative criteria*: for each candidate assignment you ask both 'does the receiving class stay describable in one sentence?' and 'does this create a new dependency, especially on something unstable?'. When they conflict, prefer the split, but reach for a **Pure Fabrication** or **Indirection** so the split does not leak dependencies everywhere — and remember that a good split usually *reduces* coupling because it puts a narrow interface between two previously entangled concerns.
go deeper
State that they are two different measures — inside a class versus between classes — and that going to either extreme is bad; give the God class and the class-explosion examples.
Add the decision procedure: evaluate both for each candidate assignment, and name Pure Fabrication as the way to keep a domain class cohesive without adding technical dependencies to it.
Point out the tension is mostly at the margins — real seams improve both — and grade dependencies by kind and stability before trading anything away.
Extend to service and team boundaries, where a bad cohesion split converts a cheap in-process call into a network hop and a distributed transaction; discuss stability/volatility and change-coupling data from version control as evidence.
## Two different axes - **Cohesion**: how strongly the elements *inside* one module belong together. Look **inward**. - **Coupling**: how much one module depends on the *internals or existence* of other modules. Look **outward**. Because they measure different directions, you can score well or badly on each independently — the famous target is the top-right quadrant: **high cohesion + low coupling**. The bottom-left, low cohesion + high coupling, is the classic legacy 'big ball of mud'. ## Why maximizing one alone fails **Cohesion taken to the extreme.** "Every class does exactly one thing" degenerates into one method per class. Consequences: dozens of types to name and locate, a collaboration graph you must traverse to understand any single feature, more constructor wiring / dependency injection, and — crucially — *more edges between modules*, which is literally more coupling. Behaviour that used to be one readable method is now spread across five files ('shotgun surgery' to change it). **Decoupling taken to the extreme.** A module with zero outbound dependencies must implement everything itself — its own parsing, its own persistence, its own formatting. That is a God class: perfectly independent, hopelessly incohesive, impossible to test or reuse. Copy-pasting code to avoid a dependency is the same mistake in miniature. ## But the tension is not symmetric — the important nuance Seniors are expected to note that **the two usually agree, not conflict**. Splitting a genuinely mixed-up class typically *lowers* total coupling, because the two concerns were previously coupled to each other through shared fields with no interface at all; after the split they talk through one narrow, explicit contract. The tension appears mostly at the *margins*, when you split beyond the natural seam. Rule of thumb: split along real seams (different reasons to change, different actors, disjoint field clusters) and coupling improves; split arbitrarily to chase a metric and coupling worsens. ## How GRASP resolves conflicts When a genuinely cohesive split would create awkward dependencies, GRASP offers the other principles as tools: - **Pure Fabrication** — invent a class that has no counterpart in the domain vocabulary (a repository, a mapper, a gateway) purely to keep the domain class cohesive without polluting it with a technical dependency. - **Indirection** — insert an intermediary so two modules do not know each other directly, converting a direct dependency into two dependencies on a stable middle. - **Protected Variations** — put a stable interface around a predicted point of change, so the split's seam is also the seam where change is absorbed. - **Information Expert** — the default home for a responsibility; cohesion is the check that keeps Expert from turning a data-rich class into a God object. ## Distinguish the *kinds* of coupling before trading anything away Not all coupling costs the same. Depending on a stable, abstract, narrow interface (data coupling — passing a value) is cheap; depending on another module's internal representation, global mutable state, or the order in which its methods must be called (content, common, and temporal coupling) is expensive. Trading a cohesion improvement for one *cheap* dependency is almost always a good deal; trading it for shared mutable state is not. Likewise, coupling to something **stable** (a language primitive, a well-specified interface you own) is far less dangerous than coupling to something volatile — this is the Stable Dependencies idea. ## Practical decision procedure 1. List candidate homes for the responsibility (Information Expert usually names one). 2. For each: would the receiving class still pass the one-sentence test? (cohesion) 3. For each: what new dependencies appear, how many, on how stable/abstract a thing? (coupling) 4. Prefer the option that is acceptable on both. If none is, introduce a Pure Fabrication or an interface (Indirection / Protected Variations) rather than accepting a God class. 5. Sanity-check with cost: a design with slightly lower cohesion but far simpler collaboration may be the better engineering answer for a small, stable component. ## Common misconception to shoot down "High cohesion causes low coupling automatically." It *tends* to help, and the two correlate in well-factored systems, but it is not a guarantee: you can build many perfectly focused classes wired into a dense, cyclic dependency web. They are independent criteria that must both be checked.
- Give a concrete case where improving cohesion also improved coupling.Extracting persistence out of a domain entity: before the split, business rules and SQL shared fields and the entity dragged a database driver into every test. After extracting a repository, the entity is pure and testable with no infrastructure dependency, and the repository depends on the entity through one narrow interface — cohesion up, coupling down.
- When would you accept a class with somewhat lower cohesion?When the split would create expensive coupling — chatty cross-boundary calls, a shared transaction that must span the pieces, or a distributed hop — or when the component is small, stable and owned by one team, so the extra indirection buys nothing. Facades and thin controllers are similar deliberate compromises.
Think of a company. Give every employee exactly one hyper-specialized task (max cohesion) and nothing gets done without a chain of five meetings (coupling explodes). Make every employee fully self-sufficient so nobody needs anyone else (max decoupling) and each one is a mediocre generalist duplicating everyone's work. Real org design finds teams that are focused and need few hand-offs.
saying these in an interview costs you the question
- Saying high cohesion automatically guarantees low coupling
- Treating 'one method per class' as the ideal end state
- Reducing coupling by duplicating code or by widening a class into a God object
- Treating all dependencies as equally costly, ignoring stability and abstractness
- Describing coupling and cohesion as opposite ends of one single scale rather than two axes