Master GRASP: 9 Essential Object‑Oriented Design Principles for Clean Code
This article explains the nine GRASP patterns and key object‑oriented design principles—such as Information Expert, Creator, Low Coupling, High Cohesion, Controller, Polymorphism, Pure Fabrication, Indirection, and Protected Variations—showing how they form the foundation for effective software architecture.
Before learning any design pattern you must understand classes and objects, because patterns only make sense when you have a solid object‑oriented foundation. GRASP (General Responsibility Assignment Software Patterns) provides nine fundamental patterns that guide how responsibilities are assigned to objects, serving as a prerequisite for mastering the 23 GoF patterns.
1. Information Expert
The class that possesses all the information needed to fulfill a responsibility should be assigned that responsibility. For example, in an online shopping cart, each product (SKU) should appear only once; the method that determines whether two SKUs are the same belongs in the product class because the SKU identifier lives there.
2. Creator
A class should create another class when it aggregates, contains, holds initialization data for, records, or frequently uses that class. For instance, an Order (the container) should create its SKU objects because the order holds the information needed to instantiate a product.
3. Low Coupling
Low coupling means reducing unnecessary connections between classes. It limits the ripple effect of changes, makes code easier to understand, and keeps classes cohesive. Coupling occurs when a class holds another as a property, calls its methods, uses it as a return value or parameter, or inherits from it. Principles such as “Don’t Talk to Strangers” advise avoiding communication between objects that do not need to interact.
4. High Cohesion
High cohesion groups tightly related responsibilities within a single class, improving understandability, reusability, and maintainability. An analogy is that each cell in a body performs a specific function without affecting others. For example, separating Excel‑related persistence and database‑related persistence into distinct DAO classes keeps each class focused on a single concern.
5. Controller
A controller receives and processes system events and is usually represented by a high‑level class such as a Processor, Coordinator, or Session.
6. Polymorphism
Polymorphism lets you treat different concrete classes uniformly through a common abstract type. For a drawing program, an abstract Shape class can be subclassed by Rectangle, Circle, etc., each overriding draw(). The client code calls shape.draw() without knowing the concrete type.
7. Pure Fabrication
When neither cohesion nor coupling can be satisfied by existing domain classes, introduce an artificial class to coordinate responsibilities. In the drawing program, an AbstractShape class can encapsulate platform‑specific rendering while keeping domain classes clean.
8. Indirection
Indirection inserts an intermediate class to decouple two modules that would otherwise be directly linked, preventing changes in one from affecting the other.
9. Protected Variations
Identify unstable points and encapsulate them behind stable interfaces, allowing future changes without modifying existing code. This is essentially the Open‑Closed Principle (OCP).
Design Principles That Outrank Patterns
Beyond patterns, enduring design principles guide good software. Key principles include:
1. Single Responsibility Principle (SRP)
A class should have only one reason to change. Mixing unrelated responsibilities creates unnecessary coupling.
2. Open‑Closed Principle (OCP)
Software entities should be extensible without modification. Adding new classes should not require changing existing ones.
3. Dependency Inversion Principle (DIP)
High‑level modules should not depend on low‑level modules; both should depend on abstractions. Details depend on abstractions, not the other way around.
4. Interface Segregation Principle (ISP)
Clients should not be forced to depend on methods they do not use. Split large interfaces into smaller, role‑specific ones.
5. Liskov Substitution Principle (LSP)
Subtypes must be substitutable for their base types without altering program correctness.
Understanding these GRASP patterns and underlying principles equips developers to write high‑cohesion, low‑coupling code, making future extensions and maintenance far easier.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITFLY8 Architecture Home
ITFLY8 Architecture Home - focused on architecture knowledge sharing and exchange, covering project management and product design. Includes large-scale distributed website architecture (high performance, high availability, caching, message queues...), design patterns, architecture patterns, big data, project management (SCRUM, PMP, Prince2), product design, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
