The same switch (or if/else chain) over a type code appears in multiple places — adding a new case means hunting them all down.
A switch on a type code that appears in multiple files; the agent adding a new case must grep for every site and update each consistently or risk silent inconsistency.
Each case becomes a class implementing a shared interface; dispatch happens once via virtual call.
Each case is a class implementing a shared interface; the agent adds a new case by adding one class, and the type system tells it what's still missing.
Before the refactoring
switch (event.kind) {case 'click': return onClick(event);case 'key': return onKey(event);}
After the refactoring
event.handle(); // ClickEvent and KeyEvent each implement handle()
Dispatch logic duplicates across files; new cases are easy to miss; the type-code coupling amplifies with every additional consumer.
Dispatch logic duplicates across files; the agent must enumerate and update every switch on every addition, with no compile-time check that the set is complete.
If only one switch on the type code exists, polymorphism is overkill — wait for the second or third repeat before extracting subclasses.
Polymorphic dispatch is implicit at call sites — the agent can no longer see the full set of branches in one place and must enumerate subclasses across files to reason about behavior.
Adding a new case is one new class; the type system surfaces what's missing.
Adding a new variant is mechanical and the type checker enforces completeness; the agent's plan-and-execute loop for new cases is bounded.
Polymorphism worship — a switch with two stable cases becomes a class hierarchy of two trivial subclasses, paying class-hierarchy overhead with no flexibility return.
Replacing every switch with polymorphism — including ones with two stable cases — creates a class hierarchy the agent must navigate without buying any extension flexibility.