Symptom

The same switch (or if/else chain) over a type code appears in multiple places — adding a new case means hunting them all down.

Goal

Each case becomes a class implementing a shared interface; dispatch happens once via virtual call.

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()
Example source: Illustrative example written for this site, not a quotation from any source.
Pressure

Dispatch logic duplicates across files; new cases are easy to miss; the type-code coupling amplifies with every additional consumer.

Tradeoff

If only one switch on the type code exists, polymorphism is overkill — wait for the second or third repeat before extracting subclasses.

Relief

Adding a new case is one new class; the type system surfaces what's missing.

Trap

Polymorphism worship — a switch with two stable cases becomes a class hierarchy of two trivial subclasses, paying class-hierarchy overhead with no flexibility return.