Object-Oriented Design

SOLID Principles

Five heuristics for object-oriented design that keep code easy to change: single responsibility, open/closed, Liskov, interface segregation, dependency inversion.

Level: advanced

What is it?

SOLID is a set of five design principles popularized by Robert C. Martin. S: a class should have one reason to change. O: open for extension, closed for modification. L: subtypes must be substitutable for their base types. I: prefer several small interfaces to one wide one. D: depend on abstractions, not on concrete details.

Why does it matter?

They are a vocabulary for talking about why a change was painful. Each principle names a kind of coupling — and each can be over-applied, so they are heuristics to weigh, not laws to follow blindly.

Mental model

The five rules a good landlord follows: each room has one purpose (S), you add rooms without rebuilding the house (O), any tenant who fits the lease can swap in (L), the lease lists only what you use (I), and the building depends on the utility contract, not on one provider (D).

How it works

  • Single Responsibility: group things that change for the same reason and separate what changes for different reasons.
  • Open/Closed: add new behavior by adding new code (a new subclass or strategy), not by editing tested code.
  • Liskov Substitution: a subtype must honor the contract of its base type, including preconditions, postconditions, and invariants.
  • Interface Segregation: no client should depend on methods it does not use. Many small interfaces beat one big one.
  • Dependency Inversion: high-level policy depends on an abstraction, and low-level details implement it. Wiring is done at the edge (dependency injection).
  • Apply them where change actually happens. Speculative abstraction is its own cost.

Steps

  • Notice a change that was painful
  • Name the coupling behind it
  • Pick the principle that addresses it
  • Refactor toward an abstraction
  • Stop when the pain is gone

Code example: Open/closed: add a discount without editing checkout

from abc import ABC, abstractmethod

class Discount(ABC):
    @abstractmethod
    def apply(self, price): ...

class NoDiscount(Discount):
    def apply(self, price):
        return price

class PercentOff(Discount):
    def __init__(self, pct):
        self.pct = pct
    def apply(self, price):
        return price * (1 - self.pct / 100)

def checkout(price, discount: Discount):   # closed for change, open for new Discounts
    return discount.apply(price)

print(checkout(200, PercentOff(25)))       # 150.0

Real-world usage

  • Code reviews: naming the coupling a change exposed
  • Designing modules and service boundaries
  • Deciding when to split a growing class

Common mistakes

  • Splitting every class into many tiny ones until no one can follow the flow.
  • Adding interfaces and factories 'in case' something changes.
  • Treating the principles as a checklist instead of a diagnosis of a real problem.

Interview questions

Explain the Single Responsibility Principle.

A class should have one reason to change — one actor or concern that drives modifications. If a report class changes for formatting and for data access, split them.

What is the Dependency Inversion Principle?

High-level modules should not depend on low-level modules; both should depend on abstractions. It lets you swap a database or service by implementing an interface, and it enables testing with fakes.

Give an example of violating Liskov substitution.

A Square subclass of Rectangle that forces width and height to be equal. Code that sets width and height separately and then checks the area breaks when it receives a Square.

LetterPrincipleA quick smell test
SSingle ResponsibilityDoes this class change for more than one reason?
OOpen/ClosedDo I edit old code every time I add a case?
LLiskov SubstitutionDoes any subclass throw or ignore what the base promises?
IInterface SegregationDo implementers leave methods empty or throw?
DDependency InversionDoes business logic construct database or network classes directly?

Prerequisites

Related concepts

Continue learning

Browse the full computer science library