principleModeratepending
Principle: Prefer composition over inheritance
Viewed 0 times
composition over inheritancefavor compositionhas-a vs is-afragile base classdesign patterns
Problem
Class hierarchies become rigid and hard to change. Adding new behavior requires modifying the hierarchy, leading to fragile base class problems.
Solution
Favor composing behavior from small, focused pieces:
When inheritance IS appropriate:
When to prefer composition:
The smell test: If your subclass overrides most methods or only uses a fraction of the parent, you want composition, not inheritance.
Practical rule: Start with composition. Switch to inheritance only when you find yourself duplicating delegation code across many classes AND there's a clear, stable hierarchy.
## Inheritance creates rigid hierarchies:
Animal
-> FlyingAnimal
-> Duck (but ducks also swim!)
-> SwimmingAnimal
-> Duck (?? can't inherit from both)
-> FlyingSwimmingAnimal (?? class explosion)
## Composition allows mixing behaviors:
interface CanFly { fly(): void }
interface CanSwim { swim(): void }
interface CanWalk { walk(): void }
class Duck implements CanFly, CanSwim, CanWalk {
private flyer = new StandardFlyer();
private swimmer = new StandardSwimmer();
fly() { this.flyer.fly(); }
swim() { this.swimmer.swim(); }
}When inheritance IS appropriate:
- True "is-a" relationships that won't change
- Framework extension points designed for it
- When you need to override specific template method steps
- Small, stable hierarchies (2-3 levels max)
When to prefer composition:
- "Has-a" or "uses-a" relationships
- Behavior that might be shared across unrelated classes
- When you need multiple independent axes of variation
- When the hierarchy is more than 3 levels deep
- When subclasses override most of the parent's behavior
The smell test: If your subclass overrides most methods or only uses a fraction of the parent, you want composition, not inheritance.
Practical rule: Start with composition. Switch to inheritance only when you find yourself duplicating delegation code across many classes AND there's a clear, stable hierarchy.
Why
Gang of Four principle. Inheritance creates compile-time coupling between parent and child. Composition creates runtime coupling that's easier to change, test, and recombine.
Context
Object-oriented design decisions
Revisions (0)
No revisions yet.