Information Expert
Give behavior to the object that has the information needed to do it well.
GRASP patterns are less famous than SOLID, but often more directly useful during design. They help answer responsibility-assignment questions: which object should perform a task, which one should create another, and which object should coordinate a system event? Those questions show up constantly in OOAD.
In order-management workflows, teams repeatedly face choices such as where totals should be calculated, who should create order lines, and whether a controller or use case object should coordinate checkout. GRASP offers practical heuristics for those decisions.
GRASP patterns help prevent responsibility from drifting into the wrong layers. Information Expert pushes behavior toward the object that knows enough to do the job. Creator encourages more natural object construction relationships. Controller keeps system event handling from leaking into UI or transport code.
These are not rigid rules. They are heuristics that guide design conversations. In Java applications, GRASP often improves both domain models and application-service boundaries.
For long-lived systems, these heuristics matter because bad responsibility assignment compounds into coupling, low cohesion, and unclear architecture.
Give behavior to the object that has the information needed to do it well.
Let one object create another when their responsibilities and relationships naturally fit.
Assign system-event coordination to an object that represents the use case or application boundary.
package org.javaomnibus.ecommerce.principles;
import java.util.ArrayList;
import java.util.List;
public final class CheckoutController {
public Order submit(CheckoutRequest request) {
Cart cart = new Cart();
for (CheckoutItem item : request.items()) {
cart.addItem(item.sku(), item.quantity(), item.unitPrice());
}
return Order.fromCart(request.customerId(), cart);
}
}
final class Cart {
private final List lines = new ArrayList<>();
void addItem(String sku, int quantity, Money unitPrice) {
lines.add(new CartLine(sku, quantity, unitPrice));
}
Money total() {
return lines.stream().map(CartLine::lineTotal).reduce(Money.zero(), Money::add);
}
List lines() {
return List.copyOf(lines);
}
}
final class Order {
static Order fromCart(String customerId, Cart cart) {
return new Order(customerId, cart.lines(), cart.total());
}
private Order(String customerId, List lines, Money total) {}
}
record CheckoutRequest(String customerId, List items) {}
record CheckoutItem(String sku, int quantity, Money unitPrice) {}
record CartLine(String sku, int quantity, Money unitPrice) {
Money lineTotal() { return unitPrice.multiply(quantity); }
}
record Money(java.math.BigDecimal amount) {
static Money zero() { return new Money(java.math.BigDecimal.ZERO); }
Money add(Money other) { return new Money(amount.add(other.amount)); }
Money multiply(int quantity) { return new Money(amount.multiply(java.math.BigDecimal.valueOf(quantity))); }
}
GRASP heuristics can point in different directions at the same time. That is normal. They are decision aids, not absolute formulas. You still need judgment about coupling, cohesion, and boundary clarity.