System Design
Object-Oriented Design
OOD Fundamentals

OOD Fundamentals

Object-Oriented Design (OOD) is built on two primary foundations: the Four Pillars of OOP and the SOLID Principles. While the pillars provide the building blocks, SOLID provides the blueprints for creating robust, maintainable systems.


The Four Pillars of OOP (Design Perspective)

In design, we look at these pillars as tools for managing complexity and change.

1. Encapsulation

Encapsulation is about bundling data and methods that operate on that data into a single unit (a class) and restricting access to some of the object's components.

  • Design Benefit: It prevents external code from accidentally corrupting an object's internal state.
  • Example: Private class fields in JavaScript (#balance).

2. Abstraction

Abstraction is the process of hiding internal details and showing only the essential features of an object.

  • Design Benefit: It simplifies the interaction between objects. Users only need to know "what" an object does, not "how."
  • Example: An Interface or an Abstract Class that defines a set of methods without implementation.

3. Inheritance

Inheritance allows a class to acquire properties and methods from another class.

  • Design Benefit: It promotes code reuse and establishes a hierarchical relationship.
  • Warning: Over-using inheritance can lead to rigid designs. Always consider Composition first.

4. Polymorphism

Polymorphism allows objects of different classes to be treated as objects of a common superclass.

  • Design Benefit: It allows you to write code that works with a variety of objects without knowing their specific types.
  • Example: A render() method that behaves differently for Circle, Square, and Triangle.

SOLID Principles

SOLID is an acronym for five design principles that make software designs more understandable, flexible, and maintainable.

S - Single Responsibility Principle (SRP)

"A class should have one, and only one, reason to change."

  • Violation: A User class that handles user data, database saving, and email notifications.
  • Fix: Split into User, UserRepository, and EmailService.

O - Open/Closed Principle (OCP)

"Software entities should be open for extension, but closed for modification."

  • Violation: An AreaCalculator that needs a new if statement every time a new shape is added.
  • Fix: Use an abstract Shape class with a calculateArea() method.

L - Liskov Substitution Principle (LSP)

"Objects of a superclass should be replaceable with objects of its subclasses without breaking the application."

  • Violation: A Square class inheriting from Rectangle but breaking the setWidth logic.
  • Fix: Ensure subclasses faithfully fulfill the contract of the parent class.

I - Interface Segregation Principle (ISP)

"Clients should not be forced to depend on methods they do not use."

  • Violation: A large Worker interface that forces a Scanner object to implement a print() method.
  • Fix: Split the large interface into smaller, more specific ones like Printer and Scanner.

D - Dependency Inversion Principle (DIP)

"High-level modules should not depend on low-level modules. Both should depend on abstractions."

  • Violation: A Switch class that carries a direct reference to a LightBulb class.
  • Fix: Both Switch and LightBulb should depend on a Switchable interface.

Best Practices for OOD

  1. Favor Composition over Inheritance: Building complex objects from smaller ones is usually more flexible than deep inheritance trees.
  2. Design for Change: Assume the requirements will change. Build in points of flexibility.
  3. Keep it DRY & KISS: Don't repeat yourself, and keep your designs as simple as possible.

Wrap Up

Mastering these fundamentals is the first step toward becoming a proficient system designer. In the next section, we will look at a 4-Step Framework to apply these principles in a real-world design interview.