Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Patterns & Design Principles  ›  Lesson

OOP and SOLID

SOLID 16 minObject-oriented design groups data with the behaviour that uses it, and the five SOLID principles keep those objects small, replaceable and loosely connected.

OOP and SOLID

DabbaGo wants to accept wallet payments. A developer opens OrderService and finds 900 lines that calculate prices, save to PostgreSQL, send SMS messages, and choose a payment method with a long if chain. Adding one payment method means editing a class that everything depends on, and every change breaks something unrelated. Object-oriented design, guided by five principles, is how architects keep code from growing into this.

The rule

Small objects, one job each, joined through interfaces.

Object-oriented programming (OOP) groups data together with the behaviour that uses it. An Order object holds its items and knows how to total them. Four ideas carry most of the weight:

  • Encapsulation: an object hides its inner data and exposes only safe operations.
  • Abstraction: callers see what an object does, not how.
  • Inheritance: a type can build on another type.
  • Polymorphism: different objects answer the same message in their own way, so pay() works for UPI, card or wallet.

SOLID names five principles for keeping objects healthy:

  • S, Single responsibility: a class should have one reason to change. Pricing rules and SMS templates change for different reasons, so they belong in different classes.
  • O, Open/closed: open to extension, closed to modification. Add a payment method by adding a class, not by editing tested code.
  • L, Liskov substitution: any subtype must work wherever its parent type is expected. If WalletPayment refuses refunds that every PaymentMethod promises, it breaks callers.
  • I, Interface segregation: prefer several small interfaces over one large one, so no class is forced to implement methods it does not use.
  • D, Dependency inversion: high-level logic depends on abstractions, and details such as PostgreSQL plug in from outside.
class PaymentMethod:            # the abstraction
    def pay(self, amount): ...

class UpiPayment(PaymentMethod):
    def pay(self, amount): ...  # talk to the UPI gateway

class WalletPayment(PaymentMethod):
    def pay(self, amount): ...  # deduct from the wallet

class OrderService:
    def __init__(self, repository, notifier):
        self.repository = repository  # any storage that saves orders
        self.notifier = notifier      # SMS, email, or a fake in tests

    def checkout(self, order, method: PaymentMethod):
        method.pay(order.total())
        self.repository.save(order)
        self.notifier.send(order.customer, "Your tiffin is booked!")

Adding wallets is now a new class. OrderService never changes.

The shortcut

For any class, ask "What would make me edit this?" List the answers.

  • More than one kind of answer → split it (S).
  • "Adding a new kind of X" is on the list → add an interface for X (O).
  • "Changing the database or provider" is on the list → invert that dependency (D).
Untangling OrderServiceStep 1 of 4
  1. List the reasons to change

    New price rules, a new database, a new SMS provider, a new payment method. Four kinds of reason: single responsibility is broken.

The trap is applying SOLID mechanically, turning a 20-line class into ten interfaces with one method each. The principles serve changeability; if nothing is likely to change, keep it simple.

Drills

Answer fast — trust the rule.

quick drill

A class formats SMS messages and also calculates tiffin prices. Which principle does it break?

quick drill

To add wallet payments without editing OrderService, what should DabbaGo do?

quick drill

Which OOP idea lets method.pay(amount) work for UPI, card and wallet alike?

quick drill

OrderService creates its own PostgreSQL connection inside checkout. Which principle does passing in a repository fix?

Remember

  • Small objects, one job each, joined through interfaces.
  • Shortcut: "what would make me edit this class?" Many kinds of answer means split.
  • Trap: applying SOLID mechanically until simple code drowns in interfaces.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainSpot the violation

DabbaGo's OrderService class calculates prices, saves orders to PostgreSQL, sends SMS messages, and has an if chain for every payment method. Name the SOLID principles it breaks and explain how you would fix it.