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 1 of 2

In the GRASP set of design principles, what does the Controller principle say about who should receive a system input event (such as a button click or an incoming HTTP request), and why?

level: juniorimportance: must knowfreq 72%

answer

  1. first non-UI receiver of a system event
  2. facade controller vs use-case controller
  3. coordinate + delegate, never compute
  4. UI knows controller; controller never knows UI
  5. testable without a screen

basics

~20 s

GRASP Controller says: don't let the UI widget itself do the work. Give the event to a separate non-UI object — a controller — that coordinates the domain objects and returns a result. This keeps screen code and business rules apart.

solid answer

~50 s

GRASP (General Responsibility Assignment Software Patterns) Controller answers: which object should be the first non-UI receiver of a system event? Answer: a dedicated coordinator object that represents either the overall system/subsystem (a facade controller) or a specific use case/session (a use-case controller). The UI element — a button handler, an HTTP endpoint, a CLI parser — only translates the raw input into a call on that controller, then renders whatever comes back. Benefits: domain logic becomes reusable across UIs (web, mobile, batch, tests); it can be unit-tested without a screen or a servlet container; the use case gets one visible entry point where transactions, authorization and validation orchestration can live. The controller itself should not implement the business rules — it delegates to domain objects and services. When it starts implementing them, it becomes a 'bloated controller', the anti-pattern the principle warns about.

code

pseudocode · 14 lines
pseudocode
// UI adapter: no business rules, only translation
onPlaceOrderClicked(form):
    cmd    = PlaceOrder(customerId: session.user, items: form.items)
    result = placeOrderHandler.handle(cmd)   // <- GRASP controller
    render(result)

// Use-case controller: coordinates, delegates, does not compute
class PlaceOrderHandler:
    handle(cmd):
        customer = customers.byId(cmd.customerId)
        order    = customer.placeOrder(cmd.items)   // rules live in the domain
        orders.save(order)
        events.publish(OrderPlaced(order.id))
        return OrderSummary(order.id, order.total)

go deeper

for a junior

Name it: the event goes to a non-UI object, not to the button handler; the controller delegates to domain objects. One concrete example is enough.

for a middle

Give both variants — facade controller and use-case (session) controller — say when each fits, and explain the reuse/testability payoff plus the bloated-controller anti-pattern.

for a senior

Connect it to layering: framework controller = adapter, GRASP controller = application/use-case layer, rules in the domain. Discuss where transactions and authorization sit, and when the extra layer isn't worth it (simple reads).

for a principal

Frame it as a boundary policy: one entry point per use case gives a consistent seam for transactions, authz, idempotency, tracing, and API versioning; explain how it maps onto hexagonal ports, CQRS handlers, and evolvability across multiple delivery channels.

## What GRASP is **GRASP** stands for *General Responsibility Assignment Software Patterns* (Craig Larman, *Applying UML and Patterns*). It is a set of nine naming-and-reasoning principles — Information Expert, Creator, **Controller**, Low Coupling, High Cohesion, Polymorphism, Pure Fabrication, Indirection, Protected Variations — each of which answers one question of the form *"which object should have this responsibility?"* They are not code structures you download; they are decision heuristics you apply while assigning responsibilities. ## The question Controller answers > A **system event** (also called a system operation or input event) has arrived — a user pressed *Place Order*, an HTTP `POST /orders` came in, a message landed on a queue, a scheduled job fired. **Which object receives it first, on the non-UI side?** Controllers exist because the alternative is worse. Without one, the natural place to put the logic is the thing that physically caught the event: the button's click handler, the web framework's request handler, the console loop. That works exactly once — until you need a second UI, a scripted/batch path, or an automated test. ## The rule, stated Assign the responsibility for handling a system input event to a class representing **one** of: 1. **The overall system, a "root object", a device, or a major subsystem** — this variant is called a **facade controller**. Example: `OrderingSystem`, `PosSystem`, `PaymentGateway`. One object fronts a whole subsystem. 2. **A use case scenario within which the event occurs** — a **use-case controller** (Larman also calls it a *session controller*), usually named `<UseCase>Handler` or `Handle<UseCase>` or `<UseCase>Service`: `PlaceOrderHandler`, `CheckoutService`, `RegisterUserUseCase`. One object per use case (or per closely related family of use cases). Crucially, the controller is a **non-UI object**. It must not import, reference, or know about widgets, HTTP request/response types, HTML, terminal escape codes, or view models of a specific framework. It speaks in domain terms and plain data. ## What the controller actually does A well-behaved controller **coordinates and delegates**; it does not compute. A typical body: 1. Convert incoming primitive/DTO input into domain concepts (or accept an already-converted command object). 2. Load the relevant domain objects via repositories/gateways. 3. Call domain methods on those objects — the business rules live *there*, per the Information Expert principle ("give the responsibility to the class that has the data needed to fulfil it"). 4. Persist / publish results, commit the unit of work. 5. Return a plain result (a DTO, an id, a domain-level outcome) to the caller. The UI layer then decides how to *display* that result. That split is the whole point: **the controller is where the use case lives; the UI is where the pixels live.** ## Why it pays off - **Reuse across delivery mechanisms.** The same `PlaceOrderHandler` serves a web form, a mobile API, a CSV importer, and a test. - **Testability.** You can drive the use case in-process with no browser, no HTTP, no framework container. This is usually the single biggest practical win. - **A place for cross-cutting concerns.** Transactions, authorization checks, idempotency keys, audit logging, metrics — all have one obvious seam per use case. - **State across events.** A use-case controller can hold or look up the state of a multi-step scenario ("we are mid-checkout, three items scanned"), which the stateless UI cannot sensibly own. - **Protection from UI churn.** Redesigning the screen, or swapping React for something else, doesn't touch the use case. ## Costs and edge cases - **Extra indirection.** For a genuinely trivial read ("show me this record") a controller layer can be ceremony. Many teams allow simple queries to go straight from the endpoint to a query object/read model and reserve controllers for state-changing operations. - **Bloat risk.** A facade controller that fronts a large system accumulates dozens of methods and unrelated state — low cohesion. The standard remedy is to split into use-case controllers. - **Controller name collision.** "Controller" in **MVC** and "controller" in a web framework (`@RestController`, `ActionController`, ASP.NET `Controller`) are *presentation-layer adapters*. GRASP Controller sits **behind** them. A framework controller that just deserializes, calls a use-case object, and serializes the answer satisfies GRASP; one that contains the business rules does not. ## Rule of thumb If you can't run your use case from a test without starting the UI or the web framework, you don't have a GRASP controller yet.

  • Does GRASP Controller mean every system event needs its own class?
    No. It says the event must be received by a non-UI coordinator; granularity is a separate choice. A facade controller can host many related events; splitting into one class per use case is the remedy you reach for when the facade loses cohesion or accumulates unrelated state.
  • If the controller must not contain business logic, where does the logic go?
    Into the domain objects that own the data needed to decide — that is the Information Expert principle. The controller only sequences calls, handles the unit of work, and shapes the reply.
  • How do you know a class is really a controller and not just a UI handler with a different name?
    Check its dependencies. If it references request/response objects, widgets, HTML, or session cookies, it's still presentation. A controller's imports should be domain types, repositories, and plain data.

A restaurant server takes your order at the table but doesn't cook it. The server is the single point of contact for your 'order' event, translates it into instructions for the kitchen, and brings back the result. Swap the dining room for a drive-through window and the kitchen doesn't change.

saying these in an interview costs you the question

  • Saying GRASP Controller is the same thing as the 'C' in MVC or a web framework's @Controller class
  • Claiming the controller should contain the business rules because 'it handles the request'
  • Assuming every controller must be stateless — a use-case/session controller may legitimately hold scenario state
  • Believing a controller must be one-per-screen (it is per system event / use case, not per view)
  • Treating the controller as an object that talks to the UI — the dependency points the other way: UI depends on controller

context

open as a page

What does the GRASP "Creator" principle say about deciding which class should be responsible for creating instances of another class?

level: juniorimportance: must knowfreq 55%

basics

~20 s

Creator says: give the job of making a new object to a class that already aggregates, contains, records, closely uses, or holds the data needed to build it. That class already knows about it, so creating it adds no new coupling.

open as a page

In the GRASP set of responsibility-assignment principles, what does High Cohesion mean, and what concrete problems does a low-cohesion class cause?

level: juniorimportance: must knowfreq 68%

basics

~20 s

Cohesion is how well everything inside one class belongs together. High Cohesion says a class should keep a small set of closely related responsibilities, so it stays easy to name, understand, change, test and reuse.

open as a page

In the GRASP set of object-oriented design principles, what does the Indirection principle say, and what problem does it solve?

level: juniorimportance: must knowfreq 55%

basics

~10 s

Indirection says: when two components would otherwise be wired directly together, put a third object between them to mediate. Neither side knows the other, so each can change or be replaced independently.

open as a page

What does the GRASP principle "Information Expert" say about where a responsibility should live, and why?

level: juniorimportance: must knowfreq 62%

basics

~20 s

Give a job to the object that already holds the data needed to do it. If an order knows its line items, the order should compute its own total, instead of another class pulling the items out first.

open as a page

In the GRASP set of object-oriented design principles, what does the Low Coupling principle say, and why does it matter?

level: juniorimportance: must knowfreq 78%

basics

~20 s

Low Coupling (GRASP) says: assign responsibilities so each class depends on as few other classes as possible. Fewer dependencies mean a change in one place breaks fewer others, and classes are easier to reuse, understand and test alone.

open as a page

What is the GRASP "Polymorphism" principle in object-oriented design, and what problem does it address?

level: juniorimportance: must knowfreq 62%

basics

~20 s

When behavior differs depending on the kind of thing you have, don't write an if/switch that checks the kind. Give each kind its own version of the operation behind one shared interface, and let the call pick the right version.

open as a page

What is the GRASP principle "Protected Variations", and what problem is it meant to solve?

level: juniorimportance: must knowfreq 55%

basics

~20 s

Protected Variations says: find the parts most likely to change or vary, and put a stable interface in front of them. Other code depends on that interface, so a change stays contained instead of rippling outward.

open as a page

In the GRASP set of object-oriented design principles, what does the Pure Fabrication principle say, and when would you apply it?

level: juniorimportance: must knowfreq 55%

basics

~20 s

Pure Fabrication says: when no real-world domain concept can hold a responsibility without spoiling the design, invent a made-up, behavior-only class for it — such as a repository, mapper, or validator — to keep cohesion high and coupling low.

open as a page

GRASP describes two kinds of controller: a facade controller (one object representing the whole system or a major subsystem) and a use-case controller (one object per use-case scenario). What are the trade-offs, and how do you decide which to use?

level: middleimportance: must knowfreq 55%

basics

~20 s

A facade controller is one object handling all events of a system — simple, fine for small apps. A use-case controller handles one scenario each — more classes, but each stays small and cohesive. Start with a facade; split when it grows.

open as a page

The GRASP "Creator" heuristic lists several criteria for choosing a creating class (aggregates, contains, records, closely uses, has initializing data). What does each mean, and how do you decide when two candidate classes both qualify?

level: middleimportance: must knowfreq 45%

basics

~20 s

Aggregates/contains means it holds the object; records means it logs instances; closely uses means it works with it heavily; has initializing data means it already knows the constructor arguments. If several fit, prefer the owner (aggregator/container); otherwise the one with the data.

open as a page

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?

level: middleimportance: must knowfreq 52%

basics

~20 s

They 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.

open as a page

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?

level: middleimportance: must knowfreq 40%

basics

~20 s

They 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.

open as a page

How does the GRASP Information Expert principle relate to "Tell, Don't Ask" and to the anemic domain model anti-pattern?

level: middleimportance: must knowfreq 55%

basics

~20 s

Information Expert says the object holding the data should do the work. That is exactly what "Tell, Don't Ask" asks for: call a method on the object instead of reading its fields and deciding outside. When you break both, entities become data bags with all logic in services — the anemic domain model.

open as a page

A codebase has a `PaymentRecord` with a `method` string field ("CARD", "BANK_TRANSFER", "WALLET"), and the same `switch (method)` appears in fee calculation, settlement-delay estimation, and receipt rendering. Walk through applying the GRASP Polymorphism principle here, and state what you gain and what you give up.

level: middleimportance: must knowfreq 54%

basics

~20 s

Create a PaymentMethod abstraction with fee(), settlementDelay(), and renderReceipt(). Add one class per method implementing all three. Map the stored string to a class once, in a factory. Callers just call the operations — the three switches disappear.

open as a page

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?

level: middleimportance: must knowfreq 45%

basics

~20 s

They 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.

open as a page

GRASP's Information Expert says to give a responsibility to the class holding the needed data, which suggests putting a save() method on the Order entity itself. Why does Pure Fabrication argue for an OrderRepository instead, and what exactly is lost or gained?

level: middleimportance: must knowfreq 45%

basics

~20 s

Order holds the data, but saving needs SQL, connections, and transactions — infrastructure knowledge. Putting save() on Order mixes two unrelated jobs and ties the business class to the database. A separate OrderRepository keeps each focused and swappable.

open as a page

Give a case where following GRASP's Information Expert produces a bad design, and name the principle you would apply instead.

level: seniorimportance: must knowfreq 44%

basics

~20 s

Saving an object to a database. A Sale knows all its own data, so Information Expert literally says sale.save(). That would force every domain class to know SQL and transactions. Instead use Pure Fabrication: a SaleRepository invented purely for design reasons.

open as a page

Applying the GRASP Information Expert principle (give a responsibility to the class holding the data it needs) sometimes produces a design with heavy dependencies. How do you use GRASP's Low Coupling principle to resolve that conflict, and what does Pure Fabrication contribute?

level: seniorimportance: must knowfreq 46%

basics

~20 s

Information Expert proposes a home for a responsibility; Low Coupling checks the bill. If the expert class would have to depend on infrastructure or many collaborators, move the responsibility to a made-up helper class — a Pure Fabrication — that keeps the domain class clean.

open as a page

Protected Variations tells you to wrap predicted points of instability. How do you decide *which* points genuinely deserve protection, and when does applying it make the design worse?

level: seniorimportance: must knowfreq 30%

basics

~20 s

Protect where change is genuinely likely and expensive to retrofit — external systems, business rules, regulated logic, vendor choices. Skip it where change is unlikely or cheap to make later; unused abstractions are pure cost: more indirection, harder reading, harder debugging.

open as a page

Developers often say "my HTTP endpoint class is my controller, so I already follow GRASP Controller." Explain how a web framework's controller (or MVC's 'C') relates to the GRASP Controller principle, and when that claim is wrong.

level: middleimportance: should knowfreq 48%

basics

~20 s

A web/MVC controller belongs to the presentation layer — it knows about requests, responses and views. GRASP's controller must not know any of that. The claim is only true if the endpoint just translates input, calls a use-case object, and formats the reply.

open as a page

In an order-entry system a controller receives "add product P with quantity 3 to order O". Applying the GRASP "Creator" heuristic, which class should construct the new order-line object, and what concretely goes wrong if the controller constructs it instead?

level: middleimportance: should knowfreq 40%

basics

~20 s

The Order should build the line, because it contains and owns its lines and holds the collection they join. If the controller builds it, the controller must know the line type, the order must expose its internal list, and totals or duplicate rules can silently break.

open as a page

Software design literature ranks cohesion on a scale from coincidental to functional. Name the main levels of that scale and give an example of a class sitting at a weak level versus a strong one.

level: middleimportance: should knowfreq 45%

basics

~20 s

From worst to best: coincidental (random stuff together), logical (same category), temporal (runs at the same time), procedural/communicational (same sequence or same data), sequential (output feeds the next step), and functional (everything serves one single task). Aim for functional.

open as a page

Adapter, Mediator, Controller, Facade, Repository and Proxy are all forms of indirection. What distinguishes them, and how do you pick the right one?

level: middleimportance: should knowfreq 45%

basics

~20 s

All put an object in the middle, but for different jobs: Adapter translates between two vocabularies, Mediator coordinates many peers, Controller receives input events, Facade simplifies a big subsystem, Repository hides storage, Proxy stands in for the real thing.

open as a page

Coupling is often described as having degrees of strength rather than being simply present or absent. Name the classic degrees of coupling from worst to best and explain what distinguishes them.

level: middleimportance: should knowfreq 52%

basics

~20 s

From worst to best: content (one element reaches into another's internals), common (shared global state), external (shared external format), control (one passes a flag telling the other what to do), stamp (passes a whole record when only a field is needed), and data (passes just the values needed).

open as a page

GRASP's Polymorphism principle says to replace type-based conditionals with polymorphic operations. In which situations is a plain conditional on type still the better design choice?

level: middleimportance: should knowfreq 38%

basics

~20 s

Keep the conditional when there is only one place that branches, when the variants come from code you can't subclass, when you're at a parsing boundary turning data into objects, or when the set of variants is closed and you want the compiler to check you handled all of them.

open as a page

Beyond interfaces and polymorphism, what concrete mechanisms can be used to achieve Protected Variations, and what are the trade-offs of each?

level: middleimportance: should knowfreq 35%

basics

~20 s

Interfaces are only one option. You can also move variation into data or configuration, use an adapter or facade around an external system, look implementations up at runtime, publish events instead of calling recipients, or adopt a standard format so vendors are interchangeable.

open as a page

You inherit a class named AccountService with 40 public methods, 14 injected dependencies, and several hundred lines of branching business rules that every screen and job in the system calls. Using GRASP reasoning, how do you diagnose and refactor it?

level: seniorimportance: should knowfreq 45%

basics

~20 s

That's a bloated controller: it receives too many events, does the work itself, and holds too much. Fix it by splitting into one coordinator per use case and pushing the actual rules down into the domain objects that own the data.

open as a page

How does the GRASP "Creator" heuristic coexist with dependency injection and a composition root? Which objects should still be created by the class that owns them, and which should be injected?

level: seniorimportance: should knowfreq 33%

basics

~20 s

Inject long-lived collaborators — services, repositories, gateways, clients — wired once at startup. Keep creating short-lived, data-carrying objects (entities, value objects, events, DTOs) inside the class that owns or has their data, as Creator says. When both are needed, inject a factory.

open as a page

When should you deviate from the GRASP "Creator" heuristic and introduce a dedicated factory (Factory Method, Abstract Factory, Builder, or a Pure Fabrication factory class) instead of letting the aggregating/using class call the constructor directly?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Deviate when construction is complicated or must vary: choosing among subclasses, reading configuration, caching or pooling, many optional parameters, or needing infrastructure like a clock or database. Then a factory keeps the owning class simple and lets the built type change.

open as a page

showing 1–30 of 49