Lesson 2 / 25
The Principles Behind the Patterns
Composition, interfaces and SOLID.
Two GoF principles and SOLID
The GoF book highlights two principles. Program to an interface, not an implementation: depend on what an object can do, not on its concrete class, so it can be swapped. Favour object composition over class inheritance: build behaviour by combining objects rather than deep subclass trees, which are rigid and leak parent details. Robert C. Martin's SOLID principles say similar things: Single responsibility (one reason to change), Open/closed (extend behaviour without editing existing code), Liskov substitution (subtypes must honour the parent's contract), Interface segregation (small, focused interfaces) and Dependency inversion (high-level code depends on abstractions). Most patterns are concrete applications of these ideas.
Inheritance versus composition
Notification sending in TypeScript.
// Inheritance: every combination needs a new subclass
class EmailNotifier { send(msg: string) { /* SMTP */ } }
class EmailAndSmsNotifier extends EmailNotifier { /* ...and so on */ }
// Composition + programming to an interface
interface Channel {
send(to: string, msg: string): Promise<void>;
}
class Notifier {
constructor(private channels: Channel[]) {}
async notify(to: string, msg: string) {
await Promise.all(this.channels.map((c) => c.send(to, msg)));
}
}
// Any mix of channels, no new classes needed
const notifier = new Notifier([new EmailChannel(), new SmsChannel()]);Principles outlive patterns
If you remember only the principles, you can often derive the pattern yourself; if you remember only the pattern names, you will apply them in the wrong places.
Quick check: What does "favour composition over inheritance" encourage?
- Building behaviour by combining objects instead of deep subclass hierarchies
- Avoiding interfaces entirely
- Putting all logic in one base class
- Using global variables for shared state
Answer
Building behaviour by combining objects instead of deep subclass hierarchies — Composition keeps parts swappable and loosely coupled.