GRASP: Why Real Architecture Starts Not with SOLID

Many developers start with SOLID and GoF patterns, but feel a gap in understanding responsibility distribution and domain modeling. GRASP fills this gap by providing a design methodology that precedes and complements SOLID.

Introduction

Many developers start with SOLID and GoF patterns, but feel a gap in understanding responsibility distribution and building a domain model. GRASP fills this gap by providing a design methodology that precedes and complements SOLID.

The Author's Personal Backstory

The author read the classics: "Clean Code" by Robert Martin, "Code Complete" by Steve McConnell, and studied SOLID, KISS, DRY. However, when reading Eric Evans' DDD, a problem emerged: the book shows tactical patterns (aggregates, value objects, specifications) and strategic approaches, but doesn't explain the methodology of designing a domain model from requirements.

Key revelation: everyone talks about OOP, but writing code in an OOP language and designing in the OOP paradigm are two different things.

Craig Larman and "Applying UML and Patterns"

Larman's book (1997) preceded DDD and offered a clear methodology:

  • Requirements and use-case analysis
  • Building a conceptual model
  • Identifying roles and responsibilities

Larman and Evans complement each other:

  • Larman provides the process of transitioning from scenarios to a model
  • Evans formalizes the language and patterns for working with the domain

Martin Fowler recommends Larman's book as the best introduction to object-oriented design.

The Nine GRASP Patterns

Group 1: Fundamental Model Principles

High Cohesion

Logically grouping responsibilities within a component simplifies maintenance, understanding, and makes the system more resilient to changes.

Low Coupling

Minimizing dependencies between modules increases modularity, reduces cascading changes, and facilitates testing.

Information Expert

If an object possesses the information to perform a task, that object should be assigned the task. This increases cohesion, eliminates duplication, and transitions from anemic models to rich domains where data and behavior are inseparable.

Creator

An object that contains, records, or actively uses another object should be responsible for its creation. This reduces coupling and localizes responsibility.

Group 2: Engineering Extensions

Pure Fabrication

Creating synthetic abstractions that don't reflect the domain but are necessary for architectural cleanliness. Example: a repository as a layer between logic and storage.

Indirection

Creating a controlled layer between objects to reduce coupling. It manifests in Proxy, Decorator, Adapter, Facade, and Repository — all of these are implementations of Indirection at different levels.

PatternFunctionIndirection
ProxyIntercepts callsIntermediate object between client and implementation
DecoratorExtends behaviorWraps with additional logic
AdapterTransforms interfaceMediator between incompatible interfaces
FacadeSimplifies accessIntermediary between client and multiple components
RepositoryAbstracts accessMediator between business logic and infrastructure

Controller

The first-link coordination pattern. A component at the system boundary (HTTP controller, gRPC endpoint, Kafka consumer) receives input data, determines the scenario, and delegates execution. A Controller can exist at different levels (UI controller, use-case controller).

Group 3: Flexibility and Resilience

Polymorphism

The ability of a function to work with objects of different types. Forms:

  • Parametric: generics List<T>
  • Ad-hoc: method overloading
  • Subtype: inheritance and interfaces

Without polymorphism, code contains conditions (if instanceof). With polymorphism, each type implements its own behavior, achieving the OCP principle (open for extension, closed for modification).

Protected Variations

Isolating potentially changeable areas with stable abstractions. Anticipate variability in advance:

AreaExample
DDDA repository protects the domain model from database changes
Hexagonal ArchitectureAdapters protect the core from APIs, UI, and brokers
Clean ArchitectureOuter layers depend on inner ones through interfaces

Protected Variations is close to SOLID's Dependency Inversion Principle (DIP): high-level code should not depend on details. It's also related to the Liskov Substitution Principle (LSP): implementations must correctly follow the abstraction's contract so that replacement is safe.

GRASP's Impact on Cohesion and Coupling

PatternImpact
Information ExpertIncreases Cohesion
CreatorReduces Coupling
Pure FabricationIncreases Cohesion
IndirectionReduces Coupling
ControllerReduces Coupling between UI and business logic, increases Cohesion
PolymorphismReduces Coupling, increases extensibility
Protected VariationsLocalizes Coupling, creates buffers for changes

Intersection of Meanings: Repository as an Example

A repository simultaneously demonstrates several patterns:

  • Pure Fabrication: it's an artificial abstraction that doesn't exist in business
  • Indirection: it serves as a layer between business logic and storage, reducing coupling

This shows how GRASP patterns complement each other at different levels of architecture.

Connection with SOLID

  • OCP (Open/Closed): achieved through Polymorphism and Protected Variations
  • DIP (Dependency Inversion): implemented by Indirection and Protected Variations
  • LSP (Liskov Substitution): guarantees the correctness of Protected Variations through behavioral contracts
  • SRP (Single Responsibility): reflected in High Cohesion and proper responsibility distribution

Key Takeaway

A mature architectural approach starts not with practices and frameworks, but with understanding principles. GRASP expresses how to think about a system at the level of architectural intuition, to choose the right tools and styles.

"He who understands the principles will find the right methods himself. And he who tries methods while ignoring principles will inevitably encounter problems." — Ralph Waldo Emerson

Knowing the principle, you can derive the practice. Knowing only the practice, it's easy to get lost in real complexity.

FAQ

What is this article about in one sentence?

This article explains the core idea in practical terms and focuses on what you can apply in real work.

Who is this article for?

It is written for engineers, technical leaders, and curious readers who want a clear, implementation-focused explanation.

What should I read next?

Use the related articles below to continue with closely connected topics and concrete examples.