skip to content

GRASP Principles

Larman's nine patterns for the question object design keeps returning to: which class should own this responsibility? They are the reasoning behind decisions that otherwise sound arbitrary, so they are useful whenever an interviewer asks why you put a method where you put it.

part ofSoftware design & architectureoverview, primer and where to startread it →
on this pageshow

explore

questions

page 2 of 2

How would you detect low cohesion in an existing class objectively, and what refactoring sequence would you apply to fix it without breaking clients?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Look for method groups touching disjoint fields (the LCOM metric captures this), vague names, and files changed by many unrelated commits. Fix by extracting each concern into its own class, keeping the old class as a delegating facade until callers migrate.

open as a page

Applying GRASP's Information Expert (assign a responsibility to the class that has the data needed) can grow a class into a God object. How do High Cohesion and Low Coupling act as a check on that, and what do you do instead?

level: seniorimportance: should knowfreq 34%

basics

~20 s

Information Expert says 'put it where the data is', which keeps piling work onto data-rich classes. Cohesion is the veto: if the class stops having one clear purpose, move the responsibility to a new invented class — GRASP calls that Pure Fabrication.

open as a page

"Any problem can be solved by adding a level of indirection — except too many levels of indirection." How do you decide when an indirection is worth adding, and what does an unjustified one cost?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Add it when you can name what it decouples: a real second implementation, an unstable external dependency, a test seam, or a place to put cross-cutting concerns. Otherwise you pay extra hops, harder debugging and more code for imagined flexibility.

open as a page

When the information a responsibility needs is spread across several objects, how do you apply GRASP's Information Expert principle?

level: seniorimportance: should knowfreq 34%

basics

~20 s

Split the job. Each object computes the part it knows and asks its neighbour for the rest — a chain of "partial experts". An order asks each line item for its subtotal; each line item asks its product for the price.

open as a page

A polymorphic call selects an implementation from the runtime type of a single receiver object. How do you handle behavior that must vary on the runtime types of TWO objects — for example, collision resolution between `Asteroid`, `Ship`, and `Missile` — and what does each approach cost?

level: seniorimportance: should knowfreq 26%

basics

~20 s

Ordinary method calls pick an implementation from one object's type only. For two, you either chain two polymorphic calls (double dispatch, as in the Visitor pattern), or look the behavior up in a table keyed by the pair of types. Both trade simplicity for extensibility.

open as a page

How does GRASP's Polymorphism principle relate to the Open–Closed Principle, the Liskov Substitution Principle, and GRASP's Protected Variations? Where can a design that uses polymorphism still violate them?

level: seniorimportance: should knowfreq 32%

basics

~20 s

Polymorphism is the usual way to achieve Protected Variations (hide a varying thing behind a stable interface) and to get Open–Closed behavior (add a class, don't edit existing code). Liskov is the condition that makes it safe: every implementation must be usable wherever the interface is expected.

open as a page

You have wrapped a third-party service behind an interface, yet a provider change still forced edits across many callers. What went wrong, and how do you diagnose and fix a protective boundary that failed?

level: seniorimportance: should knowfreq 24%

basics

~20 s

The interface probably wasn't stable: it exposed the provider's types, errors, or behaviour. If callers must know which implementation is behind the interface — for retries, error codes, ordering or quirks — the variation leaked and nothing was truly protected.

open as a page

How does GRASP's Pure Fabrication relate to two other GRASP principles — Indirection and Protected Variations — and can you have one without the others?

level: seniorimportance: should knowfreq 22%

basics

~20 s

Pure Fabrication invents a non-domain class to keep cohesion high. Indirection puts a middleman between two things so they don't touch. Protected Variations hides something unstable behind a stable interface. They overlap often, but each can occur alone.

open as a page

How do you distinguish a legitimate GRASP Pure Fabrication from an abusive "OrderManager" god-service that has drained the domain model of behavior?

level: seniorimportance: should knowfreq 32%

basics

~20 s

A good fabrication has one clearly named job, a stated reason it can't live on a domain class, few dependencies, and leaves entities holding their own rules. A god-service has a vague name, many unrelated methods, and reduces entities to data bags.

open as a page

How does the "put behavior where the data is" idea behind GRASP's Information Expert scale up to module and service boundaries in a distributed system?

level: principalimportance: should knowfreq 26%

basics

~20 s

The same rule applies to services: whichever service owns the data should own the logic and decisions about it. If one service constantly fetches another's data to decide something, the responsibility is in the wrong place — move the behavior to the data owner instead of moving the data around.

open as a page

How would you measure coupling in a codebase, and when is deliberately accepting higher coupling the better engineering decision?

level: principalimportance: should knowfreq 30%

basics

~20 s

Count incoming dependencies (afferent) and outgoing ones (efferent) per module, plus dependency-cycle checks. Accept higher coupling when the alternative is layers of indirection nobody needs — for stable, rarely-changing dependencies, or in small, short-lived, or performance-critical code.

open as a page

Connascence is a model that classifies dependencies between software elements more finely than simply calling them 'coupling'. What are its three axes, and how does it make the goal of low coupling actionable?

level: seniorimportance: nice to knowfreq 16%

basics

~20 s

Connascence means two pieces of code must change together to stay correct. It grades each dependency by strength (how hard it is to spot and fix), degree (how many places are involved) and locality (how far apart they are). Reduce strength, degree, or distance.

open as a page

Treating the GRASP controller as the single entry point per use case makes it a natural boundary for cross-cutting policy. Which concerns belong at that boundary (transactions, authorization, idempotency, tracing, validation), and what goes wrong when they are placed above it in the delivery adapter or below it in the domain?

level: principalimportance: nice to knowfreq 28%

basics

~20 s

The controller is the one place every caller passes through, so transaction start/commit, permission checks, idempotency, and tracing spans fit there. Put them in the HTTP layer and non-HTTP callers skip them; put them in entities and they get duplicated and tangled.

open as a page

At architectural scale, how does the GRASP "Creator" heuristic extend into lifecycle ownership — who may create objects that cross module or bounded-context boundaries, and how does object reconstitution by persistence frameworks interact with it?

level: principalimportance: nice to knowfreq 18%

basics

~20 s

Each module should own creation of its own types: outsiders send a request or data, and the owning module builds the object and checks the rules. Loading objects from a database is rebuilding an already-valid object, not creating a new one, so it may use a separate hidden path.

open as a page

Cohesion is usually taught at class level. How does the same principle drive boundaries at module, service and team scale, and what happens when those boundaries are drawn on the wrong criterion?

level: principalimportance: nice to knowfreq 26%

basics

~20 s

The same rule scales up: group things that change together into the same module or service. Grouping by technical layer instead of by business capability spreads every feature across many deployables, so one change needs many coordinated releases.

open as a page

How does the Indirection principle scale from a single mediating class to architectural constructs such as an anti-corruption layer, ports-and-adapters, an API gateway, or a message broker — and what changes when the indirection becomes a network hop?

level: principalimportance: nice to knowfreq 25%

basics

~20 s

The idea is the same at every scale: put something in the middle so two sides don't couple. But once the middle is a separate process, you also inherit latency, partial failure, versioning, deployment and ownership — problems a method call never had.

open as a page

At architecture scale, when does replacing type conditionals with a polymorphic subtype hierarchy make a system HARDER to evolve, and what alternatives would you reach for?

level: principalimportance: nice to knowfreq 16%

basics

~20 s

It hurts when the variation isn't really by type, when several variation axes multiply into too many classes, when the variant list is duplicated in databases, APIs and configs, or when adding new operations means changing code owned by other teams. Then prefer data-driven rules, composition, or closed types with exhaustive checks.

open as a page

How does Protected Variations manifest at architecture scale rather than class scale, and what makes an architectural boundary genuinely protective?

level: principalimportance: nice to knowfreq 16%

basics

~20 s

At architecture scale, the wrapped variation is whole systems: vendors, external partners, legacy platforms, data formats. Protection means anti-corruption layers, ports and adapters, versioned contracts and plugin points — boundaries that also match who owns and deploys each side.

open as a page

At architecture scale, what are the costs of applying GRASP's Pure Fabrication liberally, and how would you govern its use across many teams?

level: principalimportance: nice to knowfreq 12%

basics

~20 s

Each invented class adds a name to learn and a hop to follow. Overused, features spread across many thin files, entities go anemic, and reading code gets slow. Govern it with agreed roles, naming conventions, and an explicit reason for each new abstraction.

open as a page

showing 31–49 of 49