“SOLID represents five design principles: Single Responsibility Principle (one reason to change), Open/Closed Principle (open for extension, closed for modification via polymorphism), Liskov Substitution Principle (subtypes must be substitutable for base types without breaking invariants), Interface Segregation Principle (clients should not depend on unused interfaces), and Dependency Inversion Principle (depend on abstractions, not concrete classes).”
The five architectural pillars (SRP, OCP, LSP, ISP, DIP) that transform brittle spaghetti code into flexible, decoupled class hierarchies.
// Dependency Inversion & Single Responsibility Example
// 1. Abstraction (DIP)
export interface IPaymentGateway {
charge(amount: number, currency: string): Promise<boolean>;
}
// 2. High-Level Business Domain (SRP & OCP)
export class OrderProcessor {
constructor(private readonly paymentGateway: IPaymentGateway) {}
async processOrder(orderId: string, amount: number): Promise<boolean> {
console.log(`Processing order ${orderId}...`);
const success = await this.paymentGateway.charge(amount, 'USD');
if (!success) throw new Error('Payment failed');
return true;
}
}
// 3. Concrete Low-Level Implementation
export class StripeGateway implements IPaymentGateway {
async charge(amount: number, currency: string): Promise<boolean> {
// Invoke Stripe API
return true;
}
}Single Responsibility: Separate business logic, persistence, and presentation into distinct classes
Open/Closed: Introduce interfaces/abstract classes so new features are added via new implementations rather than modifying existing if/else chains
Liskov Substitution: Ensure derived classes never throw unexpected exceptions or strengthen preconditions
Interface Segregation: Break bloated fat interfaces into role-specific, focused protocols
Dependency Inversion: Inject abstract interfaces via constructor dependency injection
Applying Dependency Inversion with Interface Segregation allows 100% isolated unit testing with fast mock objects.