Object-Oriented Design Interview: Patterns and Examples
Object-oriented design questions test your ability to model real-world systems. Learn SOLID principles, key design patterns, and walk through common OOD interview problems.
Object-Oriented Design (OOD) interviews sit between coding and system design. They test your ability to model real-world entities, define relationships, and apply design patterns. OOD interview questions are common at Amazon, Microsoft, Google, and many startups.
What Interviewers Evaluate
- Requirements gathering — Can you ask clarifying questions?
- Class identification — Can you identify the right objects and their responsibilities?
- Relationship modeling — Inheritance, composition, aggregation
- SOLID principles — Do you write maintainable, extensible code?
- Design patterns — Do you know when to apply them?
SOLID Principles
S — Single Responsibility Principle
A class should have only one reason to change. Don't put user authentication, email sending, and database queries in the same class.
O — Open/Closed Principle
Classes should be open for extension but closed for modification. Use interfaces and abstract classes to allow new behavior without changing existing code.
L — Liskov Substitution Principle
Subclasses should be substitutable for their base classes. If Square extends Rectangle, any code using Rectangle should work correctly with Square.
I — Interface Segregation Principle
Don't force classes to implement interfaces they don't use. Prefer many small interfaces over one large interface.
D — Dependency Inversion Principle
Depend on abstractions, not concrete implementations. High-level modules shouldn't depend on low-level modules — both should depend on interfaces.
Essential Design Patterns for Interviews
Strategy Pattern
Define a family of algorithms, encapsulate each one, and make them interchangeable.
interface PaymentStrategy {
pay(amount: number): void;
}
class CreditCardPayment implements PaymentStrategy {
pay(amount: number) { console.log('Paid ' + amount + ' via credit card'); }
}
class UPIPayment implements PaymentStrategy {
pay(amount: number) { console.log('Paid ' + amount + ' via UPI'); }
}
class PaymentProcessor {
constructor(private strategy: PaymentStrategy) {}
processPayment(amount: number) { this.strategy.pay(amount); }
}
Observer Pattern
When one object changes state, all its dependents are notified automatically. Used in event systems, pub/sub, and reactive programming.
Factory Pattern
Create objects without specifying the exact class. Useful when the creation logic is complex or depends on configuration.
Singleton Pattern
Ensure a class has only one instance. Use sparingly — it's essentially a global variable. Common for database connections, loggers, and configuration managers.
The OOD Interview Framework
- Clarify requirements (3-5 min) — What features? What scale? What actors?
- Identify core objects (5 min) — Nouns in requirements become classes
- Define relationships (5 min) — Has-a, is-a, uses
- Design interfaces and methods (10 min) — Public APIs for each class
- Walk through a scenario (5 min) — Trace a user story through your design
- Discuss trade-offs (5 min) — Extensibility, performance, edge cases
Example: Design a Parking Lot System
Requirements: Multiple floors, different vehicle sizes, ticket-based entry/exit, hourly pricing.
// Core entities
class ParkingLot {
floors: ParkingFloor[];
entryPanels: EntryPanel[];
exitPanels: ExitPanel[];
getAvailableSpot(vehicleType: VehicleType): ParkingSpot | null { /* ... */ }
}
class ParkingFloor {
floorNumber: number;
spots: ParkingSpot[];
getAvailableSpots(type: VehicleType): ParkingSpot[] { /* ... */ }
}
class ParkingSpot {
id: string;
type: SpotType; // COMPACT, REGULAR, LARGE
isOccupied: boolean;
vehicle: Vehicle | null;
assignVehicle(vehicle: Vehicle): void { /* ... */ }
removeVehicle(): void { /* ... */ }
}
class Vehicle {
licensePlate: string;
type: VehicleType; // MOTORCYCLE, CAR, TRUCK
}
class ParkingTicket {
id: string;
spot: ParkingSpot;
vehicle: Vehicle;
entryTime: Date;
exitTime: Date | null;
calculateFee(): number { /* hourly rate * duration */ }
}
enum VehicleType { MOTORCYCLE, CAR, TRUCK }
enum SpotType { COMPACT, REGULAR, LARGE }
Example: Design an LRU Cache
class LRUCache {
private capacity: number;
private cache: Map<string, any>;
constructor(capacity: number) {
this.capacity = capacity;
this.cache = new Map();
}
get(key: string): any {
if (!this.cache.has(key)) return -1;
// Move to end (most recently used)
const value = this.cache.get(key);
this.cache.delete(key);
this.cache.set(key, value);
return value;
}
put(key: string, value: any): void {
if (this.cache.has(key)) this.cache.delete(key);
this.cache.set(key, value);
// Evict oldest if over capacity
if (this.cache.size > this.capacity) {
const oldest = this.cache.keys().next().value;
this.cache.delete(oldest);
}
}
}
Common OOD Interview Questions
- Design a Parking Lot System
- Design an LRU Cache
- Design a Library Management System
- Design an Elevator System
- Design a Chess Game
- Design a Vending Machine
- Design a Hotel Booking System
- Design a File System
Conclusion
OOD interviews reward clear thinking, good communication, and knowledge of design patterns. Practice the framework, study SOLID principles, and work through 4-5 common problems end-to-end. This bridges the gap between pure coding patterns and large-scale system design.
Preparing for design interviews? Try InterviewAlly free and get AI-powered assistance for every interview round.