A subclass that overrides several methods to implement variant behavior — `PremiumBooking extends Booking` overriding `charge()`, `discount()`, `notify()` with premium variants.
Behavior that varied via inheritance now varies via a delegate object that implements the variant interface.
Before the refactoring
class Booking { /* ... */ }class PremiumBooking extends Booking {/* overrides several methods */}
After the refactoring
class Booking {type; // 'standard' | premium delegatecharge() { return this.type.charge(this); }}
Behavior can't change at runtime; combining variants requires multiple inheritance; the inheritance relationship may violate Liskov in subtle ways.
Composition is more verbose at construction sites — accept the verbosity in exchange for the flexibility.
Variants can be combined or swapped at runtime; Liskov violations vanish; the hierarchy tree flattens.
Replacing every subclass with composition — including ones where the inheritance contract genuinely holds — pays construction-site verbosity for no real fit improvement.