In the previous chapter, we learned that one of the most important questions in software design is:
Who should do this?
Suppose we are designing an online shopping system.
Requirement:
Calculate order totalPossible objects:
Customer
Order
Product
PaymentWho should calculate it?
Or consider:
Create a ReservationPossible objects:
Guest
Hotel
Reservation
BookingServiceWho should create it?
Without a systematic framework, responsibility assignment becomes guesswork.
To solve this problem, software engineering introduced: GRASP
What is GRASP?
GRASP stands for:
General Responsibility Assignment Software PatternsCreated by: Craig Larman
GRASP is not a design pattern catalog like Factory or Observer.
Instead:
GRASP is set of principles for deciding where responsibilities should live.
Think of GRASP as:
SOLID → How classes should behave
Design Patterns → Reusable solutions
GRASP → How responsibilities are assignedWhy GRASP Matters
Most bad design suffer from:
Wrong object doing the work
God Objects
Anemic Models
High Coupling
Low CohesionGRASP directly targets these problems.
The 9 GRASP Principles
1. Information Expert
2. Creator
3. Controller
4. Low Coupling
5. High Cohesion
6. Polymorphism
7. Pure Fabrication
8. Indirection
9. Protected VariationsThese principles are often applied simultaneously.
Principle 1 – Information Expert
The Problem
Requirement:
Calculate Order TotalWho should do it?
Candidates:
Customer
Order
PaymentService
InvoiceGeneratorPrinciple
Assign responsibility to the class that has the information needed to fulfill it.
Example:
Order contains:
Items
Prices
QuantitiesTherefore:
class Order
{
public:
double calculateTotal();
};Bad:
class Customer
{
public:
double calculateOrderTotal(Order&);
};Customer lacks required information.
Mental Model
Ask:
Who knows the data?
The answer often receives the responsibility.
Production Example
Library System
Requirement:
Is this book available?
Book knows:
Available Copies
StatusTherefore:
book.isAvailable();Book is the expert.
Benefits
- High Cohesion
- Simple Design
- Natural Behavior Placement
Princple 2 – Creator
The Problem
Requirement:
Create OrderItemQuestion:
Who should create it?Principle
A class should create another object if:
It contains it
It aggregates it
It records it
It closely uses it
It has initialization informationExample:
Order
|
contains
|
OrderItemTherefore:
class Order
{
public:
void addItem(...)
{
items.push_back(
OrderItem(...)
);
}
};Order creates OrderItem.
Why?
Order owns:
Lifecycle
Collection
Business RulesBad Design
class Customer
{
public:
OrderItem createOrderItem();
};Custsomer has no natural relationship.
Production Example
ATM
ATM creates Transaction
because ATM manages transactions.
Principle 3 – Controller
The Problem
Suppose a user clicks:
Place OrderWhich object receives the request?
Bad:
UI directly manipulates every domain object.Creates chaos.
Principle
Use a controller object to handle system events.
Example:
User
|
v
OrderController
|
v
OrderExample:
class OrderController
{
public:
void placeOrder()
{
// coordinate workflow
}
};Controller responsibilities:
Receive requests
Coordinate workflow
Delegates workController should NOT:
Contain business logicBad:
class OrderController
{
public:
void placeOrder()
{
// 500 lines
// all business logic
}
};Good:
controller
↓
order
↓
payment
↓
inventoryController coordinates.
Domain objects work.
Principle 4 – Low Coupling
Definition
Coupling measures dependency between classes.
Goal:
Minimize dependenciesBad Example:
class Order
{
private:
PaymentGateway gateway;
Database database;
Logger logger;
Cache cache;
Email email;
};Order depends on everything.
Problems:
Difficult Testing
Difficult Changes
Fragile DesignBetter:
class Order
{
private:
PaymentService* payment;
};Fewer dependencies.
Mental Model
Ask:
If this class changes, how many classes break?Fewer is better.
Principle 5 – High Cohesion
Definition
Cohesion measuress how focused responsibilities are.
Good Example:
class Order
{
public:
addItem();
removeItem();
calculateTotal();
markPaid();
};Everything relates to orders.
Bad Example:
class Order
{
public:
calculateTotal();
sendEmail();
resizeImage();
uploadVideo();
generateReport();
};Low cohesion.
Mental Model
Ask:
Do these responsibilities belong together?
If not:
Split the class.
Principle 6 – Polymorphism
The Problem
Suppose:
Credit Card
UPI
PayPalAll support payment.
Bad:
if(type == CREDIT)
{
}
else if(type == UPI)
{
}
else if(type == PAYPAL)
{
}Principle
Use polymorphism instead of conditionals.
Example:
class PaymentMethod
{
public:
virtual void pay() = 0;
};class CreditCard : public PaymentMethod
{
public:
void pay() override;
};class UPI : public PaymentMethod
{
public:
void pay() override;
};Usage:
paymentMethod->pay();No conditional logic.
Benefits
Extensible
Maintainable
OCP FriendlyPrinciple 7 – Pure Fabrication
The Problem
Sometimes no natural domain object fits.
Example
Requirement:
Save Customer to DatabaseQuestion:
Should Customer save itself?Bad:
class Customer
{
public:
saveToDatabase();
};Now Customer knows SQL.
Violation:
Low Cohesion
High CouplingSolution
Create artificial class.
class CustomerRepository
{
public:
void save(Customer&);
};Repository doesn't exist in business domain.
We create it to improve design.
This is Pure Fabrication
Benefits
Better Separation
Higher Cohesion
Lower CouplingPrinciple 8 – Indirection
Problem
Two objects become tightly coupled.
Example:
Order
|
directly
|
PaymentGatewayIf gateway changes:
Order changesSolution
Introduce intermediary.
Order
|
PaymentService
|
PaymentGatewayExample:
class PaymentService
{
public:
virtual void process() = 0;
};Benefits
Reduced Dependency
Flexibility
TestabilityPrinciple 9 – Protected Variations
Problem
Some parts of systems change frequently.
Examples:
Payment Providers
Notification Systems
Databases
Shipping ProvidersPrinciple:
Protect stable parts from unstable parts.
Bad
Order
|
v
Stripe APIOrder tied directly to Stripe.
Better
Order
|
Payment Interface
|
Stripe
PayPal
RazorpayExample
class PaymentProcessor
{
public:
virtual void process() = 0;
};Implementations
StripeProcessor
PayPalProcessor
RazorpayProcessorOrder depends on abstraction
Not implementation.
How GRASP Principles Work Together
Real design rarely use one principle.
Example
E-Commerce Checkout
Information Expert: Order calculates total.
Creator: Order creates OrderItem.
Controller: Order depends on Payment Interfaces.
High Cohesion: Order manages only order concerns.
Polymorphism: Different payment methods.
Pure Fabrication: OrderRepository.
Indirection: PaymentService.
Protected Variations: PaymentProcessor Interface.Complete Example
User
|
v
CheckoutController
|
v
Order
|
+------> OrderItem
Order
|
v
PaymentProcessor
|
+---- Stripe
|
+---- PayPal
|
+---- UPIIndustry Perspective
Many enterprise architectures unconsciously follow GRASP.
Examples:
Spring Applications
.NET Applications
Large C++ Systems
MicroservicesGRASP influenced many later concepts including:
SOLID
DDD
Clean Architecture
Hexagonal ArchitectureExpert Notes
One of the most important realizations in software design:
There is rarely a perfect for a responsibility.
Design is often about choosing the least problematic option.
GRASP provides a framework for making those decisions consistently.
Another insight:
Information Expert and High Cohesion solve most beginner design problems.
If you simply ask:
Who owns the information?
Will this increase cohesion?your design improve dramatically.
Finally:
GRASP is about thinking, not memorization.
The goal is not remembering nine names.
The goal is learning how architects reason about responsibility placement.
GRASP provides a systematic framework for assigning responsibilities.
The nine principles are:
| Principle | Purpose |
|---|---|
| Information Expert | Assign responsibility to information owner |
| Creator | Decide who creates objects |
| Controller | Handle system events |
| Low Coupling | Reduce dependencies |
| High Cohesion | Keep responsibilities focused |
| Polymorphism | Replace conditionals |
| Pure Fabrication | Create helper abstractions |
| Indirection | Decouple components |
| Protected Variations | Isolate change |
Leave a comment
Your email address will not be published. Required fields are marked *
