1. The problem OOP was trying to solve
In the late 1950s and early 1960s, programs were written as long sequences of procedures operating on shared global data. As programs grew, this broke down:
- Any function could change any data, so bugs spread across the whole codebase.
- Real-world things (a ship, a customer, a bank account) had no single home in the code; their data and behaviour were scattered.
- Reusing code meant copy-paste.
Researchers wanted a way to model the world as a set of self-contained things that talk to each other. That idea became object-oriented programming.
2. Timeline: how OOP was invented
| Year | Milestone | Who | Why it matters |
|---|---|---|---|
| 1963 | Sketchpad | Ivan Sutherland (MIT) | Graphics system with "master" drawings and "instances" — an early form of class/object. |
| 1962–1967 | Simula I → Simula 67 | Ole-Johan Dahl & Kristen Nygaard (Norwegian Computing Center, Oslo) | The first OOP language. Built for simulations (ships, queues, traffic). Simula 67 introduced classes, objects, inheritance, subclasses, and virtual methods. |
| ~1966–67 | The term "object-oriented" | Alan Kay | Kay coined the phrase, inspired by Sketchpad, Simula, and biology (cells communicating via messages). |
| 1972–1980 | Smalltalk (72, 76, 80) | Alan Kay, Dan Ingalls, Adele Goldberg (Xerox PARC) | Made OOP "pure": everything is an object, objects communicate by sending messages. Also gave us the GUI, windows, and MVC. |
| 1979 → 1983 | "C with Classes" → C++ | Bjarne Stroustrup (Bell Labs) | Brought Simula's ideas to C's performance. Took OOP into mainstream industry. |
| 1984 | Objective-C | Brad Cox & Tom Love | Smalltalk-style messaging on C; later the basis of NeXT and Apple's platforms. |
| 1994 | "Design Patterns" (Gang of Four) | Gamma, Helm, Johnson, Vlissides | Catalogued 23 reusable OOP design solutions. Turned OOP into a design discipline. |
| 1995 | Java | James Gosling (Sun) | "Write once, run anywhere"; made class-based OOP the default for enterprise software. |
| 2000s | SOLID principles | Popularised by Robert C. Martin | Rules for building maintainable OO systems. |
| 2001 / 2003 | Turing Awards | Dahl & Nygaard (2001), Alan Kay (2003) | Recognition of OOP as a foundational idea in computing. |
Two schools of OOP
- Simula / C++ / Java school — OOP as classes and inheritance: define types, build hierarchies.
- Smalltalk / Alan Kay school — OOP as objects sending messages: independent actors hiding their state.
Kay later said the big idea was messaging, not classes. That view is surprisingly close to modern microservices and actor systems (Erlang, Akka).
3. The four pillars
3.1 Encapsulation — hide state, expose behaviour
class BankAccount {
#balance = 0; // private: nobody outside can touch it directly
deposit(amount: number) {
if (amount <= 0) throw new Error("Invalid amount");
this.#balance += amount;
}
getBalance() {
return this.#balance;
}
}
Invariants (balance never goes invalid) are enforced in one place.
3.2 Abstraction — expose what, hide how
interface PaymentGateway {
charge(userId: string, amount: number): Promise<string>;
}
Callers depend on the contract, not on Razorpay/Stripe details.
3.3 Inheritance — reuse and specialise
class Notification {
constructor(protected to: string) {}
send() { /* common logging, retries */ }
}
class EmailNotification extends Notification {
override send() { /* SMTP */ super.send(); }
}
Useful, but easy to overuse (see "composition over inheritance" below).
3.4 Polymorphism — one interface, many implementations
const channels: Notification[] = [new EmailNotification("a@x.com"), new SmsNotification("+91...")];
channels.forEach(c => c.send()); // each does its own thing
The caller doesn't need if/else on type — new types plug in without changing old code.
4. Why OOP is a building block of system design
System design has two levels:
- High-Level Design (HLD): services, databases, queues, caches, load balancers.
- Low-Level Design (LLD): classes, interfaces, relationships, and patterns inside each service.
OOP is the language of LLD, and its ideas scale up to HLD.
4.1 Objects map to domain concepts
Designing a parking lot, Uber, or an LMS starts with nouns → classes:
User, Driver, Ride, Payment, Location
Course, Module, Lesson, Quiz, Attempt, Progress
Verbs → methods: ride.start(), quiz.submit(), payment.refund().
4.2 Relationships define structure
| Relationship | Meaning | Example |
|---|---|---|
| Association | uses / knows about |
Driver — Ride
|
| Aggregation | has-a, can live independently |
Course has Students
|
| Composition | owns, dies with parent |
Order owns OrderItems
|
| Inheritance | is-a |
AdminUser is a User
|
| Dependency | temporarily uses |
ReportService uses PdfGenerator
|
4.3 SOLID — the rules that keep systems changeable
| Principle | One-line meaning | System-design payoff |
|---|---|---|
| S — Single Responsibility | A class has one reason to change | Small, testable units; mirrors "one service, one job" |
| O — Open/Closed | Open for extension, closed for modification | Add a new payment method without touching old code |
| L — Liskov Substitution | Subtypes must be usable as their base type | Safe polymorphism; no surprise breakages |
| I — Interface Segregation | Many small interfaces > one fat one | Clients depend only on what they use |
| D — Dependency Inversion | Depend on abstractions, not concretions | Swap DB/queue/vendor easily; easy mocking in tests |
// Dependency Inversion in practice
class OrderService {
constructor(
private repo: OrderRepository, // interface, not MongoRepo
private payments: PaymentGateway, // interface, not StripeClient
) {}
}
4.4 Composition over inheritance
Deep inheritance trees become rigid. Modern design prefers composing behaviour:
class Car {
constructor(private engine: Engine, private gps: Navigator) {}
}
Swap PetrolEngine for ElectricEngine without a new subclass.
4.5 Design patterns — reusable OOP solutions
| Category | Pattern | Typical use |
|---|---|---|
| Creational | Factory, Builder, Singleton | Creating notification channels, building complex queries, one DB pool |
| Structural | Adapter, Decorator, Facade | Wrapping a third-party API, adding caching/logging, simplifying a subsystem |
| Behavioural | Strategy, Observer, State, Command | Pricing/ranking algorithms, event listeners, order lifecycle, undo/queue jobs |
4.6 The same ideas scale to HLD
| OOP concept | Distributed-system equivalent |
|---|---|
| Object | Microservice / actor |
| Encapsulation | Service owns its own database |
| Interface | API contract (REST, gRPC, OpenAPI) |
| Message passing (Kay) | Events, queues (Kafka, RabbitMQ) |
| Polymorphism | Multiple implementations behind one API / load balancer |
| Dependency Inversion | Service discovery, config-driven adapters |
| Observer pattern | Pub/Sub |
This is why interviewers ask LLD questions (parking lot, elevator, BookMyShow) — they test whether you can think in objects, contracts, and responsibilities, which is the same thinking HLD requires.
5. Criticism and balance
- Over-engineering: too many layers, factories, and abstract classes for simple problems.
- Inheritance misuse: fragile base classes, deep hierarchies.
- Shared mutable state: objects still mutate state; concurrency gets hard.
- Functional programming (immutability, pure functions) has pushed back on this, and most modern code (TypeScript, Kotlin, Rust, Swift) is multi-paradigm: objects for structure, functions for transformations.
Rule of thumb: use OOP to draw boundaries and contracts; keep logic inside those boundaries simple.
6. Quick LLD recipe
- Clarify requirements and use cases.
- Extract nouns → candidate classes; verbs → methods.
- Define interfaces at boundaries (storage, payment, notification).
- Draw relationships (class diagram).
- Apply SOLID; pick patterns only where they remove real complexity.
- Handle concurrency, errors, and extensibility.
- Walk through one use case end to end.
7. Summary
- Invented: Simula 67 (1967) by Dahl & Nygaard in Norway was the first OOP language; Alan Kay coined "object-oriented" and built Smalltalk at Xerox PARC in the 1970s; C++ (1983) and Java (1995) made it mainstream.
- Core ideas: encapsulation, abstraction, inheritance, polymorphism.
- Why it matters for system design: OOP gives you the vocabulary of components with responsibilities that communicate through contracts — exactly what both low-level and high-level design are about.
Top comments (0)