replace-conditional-polymorphism
Replace a type-switch or repeated type-checks with polymorphism so each subclass handles its own behaviour.
SKILL.mdskills/code-quality/replace-conditional-polymorphism/SKILL.md
GitHubReplace Conditional with Polymorphism
When you switch on a type code to perform different behaviour, adding a new type means editing every switch. Polymorphism moves each case into its own class.
When to Use
- A
switchor chain ofif/else ifchecks a type/kind field - The same type check appears in multiple places
- Adding a new type requires touching many methods
- Objects already differ by a type field that drives behaviour
How to Apply
- Create a superclass or interface with the method that varies
- Create a subclass for each type-code value
- Move the corresponding
caselogic into each subclass's override - Replace the conditional dispatch with a polymorphic call
- Run tests; remove the original conditional
Example
// Before
function speed(bird: Bird): number {
switch (bird.type) {
case 'EuropeanSwallow': return 35;
case 'AfricanSwallow': return Math.max(0, 40 - 2 * bird.numberOfCoconuts);
case 'NorwegianBlueParrot': return bird.isNailed ? 0 : 10 + bird.voltage / 10;
}
}
// After
abstract class Bird { abstract speed(): number; }
class EuropeanSwallow extends Bird { speed() { return 35; } }
class AfricanSwallow extends Bird { speed() { return Math.max(0, 40 - 2 * this.numberOfCoconuts); } }
class NorwegianBlueParrot extends Bird { speed() { return this.isNailed ? 0 : 10 + this.voltage / 10; } }