Replace Type Code with Subclasses

Compare
Symptom
Human

A class with a `kind` or `type` field (string or enum) plus methods that switch on it — `Employee` carrying a `type` field used to dispatch `bonus()` to different formulas.

Agent

A class with a kind field plus methods that switch on it; the agent adding a new kind must find every switch and update each consistently.

Goal
Human

A 'kind' string field becomes a real subclass type; the type system enforces the legal set.

Agent

Each kind is a subclass; the agent adds a new kind by adding one class, and the type system tells it what's still missing.

Before the refactoring

class Employee {
type; // 'engineer' | 'manager'
bonus() {
switch (this.type) {
case 'engineer': return this.salary * 0.10;
case 'manager': return this.salary * 0.15 + this.reports.length * 100;
}
}
}

After the refactoring

class Employee {}
class Engineer extends Employee {
bonus() { return this.salary * 0.10; }
}
class Manager extends Employee {
bonus() { return this.salary * 0.15 + this.reports.length * 100; }
}
Example source: Illustrative example written for this site, not a quotation from any source.
Pressure
Human

Every method that varies by type must switch; the compiler can't enforce that all kinds are handled; new kinds require updating every switch.

Agent

The agent must enumerate every switch on every addition; the type system can't enforce completeness so the agent verifies by grep.

Tradeoff
Human

If only one or two switches exist on the type code, subclassing is over-design; combine with Replace Conditional with Polymorphism only when dispatch repeats.

Agent

If only one or two switches exist on the type code, the subclass hierarchy is over-design; the agent now navigates a class tree for what was a single switch.

Relief
Human

Compile-time checks that no kind is missed; per-kind behavior lives where it belongs.

Agent

Adding a new kind is mechanical and type-system-enforced; the agent's plan-and-execute loop for new variants is bounded.

Trap
Human

Replacing the type code with subclasses when only one or two switches exist on it — over-design for a coordination point that's barely a smell.

Agent

Subclassing for type codes used in only one or two switches creates a hierarchy the agent must navigate for a coordination cost that was already small.