Mastering OOP: Essential Design Principles Every Developer Should Know
This article explains core object‑oriented design principles—including DRY, YAGNI, Rule of Three, GRASP, SOLID and other fundamental guidelines—illustrated with real‑world examples and diagrams to help developers write cleaner, more maintainable code.
Background
Object‑oriented basics give us a concept, but designing good OO code requires supporting design principles. These principles guide the design, and through practice and abstraction they evolve into design patterns. Mastering design patterns therefore starts with understanding fundamental design principles.
1. Three Principles of Code Abstraction
1.1 DRY (Don’t Repeat Yourself) – Each functionality should have a single implementation. When the same problem appears multiple times, abstract a common solution instead of duplicating code. Example: extracting shared SMS‑sending logic for reminder and verification messages.
1.2 YAGNI (You Aren’t Gonna Need It) – Do not add features beyond the core functionality. Keep the code minimal to get it running quickly; avoid unnecessary logging, checks, or exception handling.
1.3 Rule of Three – Only abstract a solution after the same functionality appears three times. The first two times you may copy code; on the third occurrence you create a reusable abstraction.
Relationship among the three – DRY pushes for abstraction, YAGNI for simplicity, and Rule of Three balances the two by providing a metric for when to abstract.
2. GRASP Principles
GRASP (General Responsibility Assignment Software Patterns) focuses on assigning responsibilities to achieve high cohesion. It includes nine patterns; the article highlights several:
2.1 Information Expert – Assign a responsibility to the class that has all the information needed to fulfill it. Example: placing the method that compares product SKUs inside the Product class because only the Product knows its SKU.
2.2 Creator – The class that aggregates, contains, holds initialization data for, records, or frequently uses another class should create that class. Example: Order creates Product because Order is the container of products and holds the necessary initialization data.
2.3 Low Coupling – Reducing inter‑class dependencies makes changes less impactful and the system easier to understand. The article lists typical coupling scenarios and shows how keeping responsibilities within the appropriate class (e.g., adding a TotalPrice method to Order) maintains low coupling.
2.4 High Cohesion – A class should have tightly related responsibilities. Example: separating Excel and database persistence into distinct DAO classes improves cohesion and modularity.
2.5 Controller – Handles system events, typically a high‑level class (e.g., *Controller) in MVC architectures.
2.6 Polymorphism – Enables different implementations of the same interface, supporting high cohesion and low coupling. Example: an abstract Shape class with Rectangle, Circle, and Diamond subclasses each overriding Draw().
2.7 Pure Fabrication – Introduce a non‑domain class to achieve low coupling and high cohesion when they conflict. Example: an AbstractShape class mediates drawing across different system APIs without altering existing domain classes.
2.8 Indirection – Insert an intermediary to decouple two classes, preventing direct strong coupling.
2.9 Protected Variations – Isolate unstable parts behind interfaces so changes affect only the implementation, not the clients. Example: abstracting payment methods behind a Payment interface.
3. SOLID Principles
3.1 Single Responsibility Principle (SRP) – A class should have only one reason to change.
3.2 Open/Closed Principle (OCP) – Software entities should be open for extension but closed for modification.
3.3 Liskov Substitution Principle (LSP) – Subtypes must be substitutable for their base types without altering correctness.
3.4 Least Knowledge Principle (Law of Demeter) – Minimize interactions between objects to reduce coupling.
3.5 Interface Segregation Principle (ISP) – Prefer many small, specific interfaces over a few large, general ones.
3.6 Dependency Inversion Principle (DIP) – Depend on abstractions, not concretions; high‑level modules should not depend on low‑level modules.
4. Other Design Principles
Composition/Aggregation Reuse (CARP), Acyclic Dependencies (ADP), Common Closure (CCP), Common Reuse (CRP), Hollywood Principle, KISS, Convention over Configuration, Command‑Query Separation, Separation of Concerns, Design by Contract, etc.
Conclusion
The article presented common design principles that guide code design, architecture reviews, and code reviews. These principles form the foundation for design patterns, which will be covered in the next article focusing on the 23 GoF patterns.
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.
