Replace Subclass with Delegate

Compare
Symptom
Human

A subclass that overrides several methods to implement variant behavior — `PremiumBooking extends Booking` overriding `charge()`, `discount()`, `notify()` with premium variants.

Agent

A subclass that overrides several methods to implement variant behavior; the agent reasoning about polymorphic dispatch must enumerate variants across the hierarchy.

Goal
Human

Behavior that varied via inheritance now varies via a delegate object that implements the variant interface.

Agent

Variants live in delegate objects the host holds and forwards to; the agent reads one host class plus the held delegate's interface instead of climbing an inheritance chain to predict behavior.

Before the refactoring

class Booking { /* ... */ }
class PremiumBooking extends Booking {
/* overrides several methods */
}

After the refactoring

class Booking {
type; // 'standard' | premium delegate
charge() { return this.type.charge(this); }
}
Example source: Illustrative example written for this site, not a quotation from any source.
Pressure
Human

Behavior can't change at runtime; combining variants requires multiple inheritance; the inheritance relationship may violate Liskov in subtle ways.

Agent

Behavior can't change at runtime; combining variants requires multiple inheritance the agent must work around; Liskov violations hide in override behavior.

Tradeoff
Human

Composition is more verbose at construction sites — accept the verbosity in exchange for the flexibility.

Agent

Composition is more verbose at construction sites; the agent loses syntactic polymorphism and must verify behavior through explicit delegation calls.

Relief
Human

Variants can be combined or swapped at runtime; Liskov violations vanish; the hierarchy tree flattens.

Agent

Behavior changes at runtime by swapping the delegate; the agent reasons against one host signature plus the delegate's interface, without loading the inheritance graph to verify which override applies to a given instance.

Trap
Human

Replacing every subclass with composition — including ones where the inheritance contract genuinely holds — pays construction-site verbosity for no real fit improvement.

Agent

Replacing inheritance with delegation on hierarchies where every subclass honors the parent's contract adds construction-site setup and a forwarding method per parent method without changing what the agent's generated calls do.