Switch Statement Smell
Also Known As
switch statement smell
type switch
conditional dispatch
TL;DR
Repeated switch/if-elseif chains on the same type indicator signal a missing polymorphic design.
Explanation
Switch statements on a type or status field scattered across a codebase indicate that object-oriented polymorphism is the appropriate design. Each time a new type is added, every switch must be updated — a violation of the Open/Closed Principle. The refactoring is Replace Conditional with Polymorphism: create a class hierarchy where each subclass provides its own implementation of the varying behaviour. PHP 8.0's match expression is not a remedy for this smell — it's a better syntax for the same structural problem.
Common Misconception
✗ Switch statements are always a code smell. Simple data lookups and exhaustive enum matches are perfectly fine uses of switch. The smell is when switch on a type tag duplicates logic across the codebase that polymorphism would centralise.
Why It Matters
A switch on object type is often a missed polymorphism opportunity — it must be updated everywhere the type distinction matters, violating Open/Closed Principle.
Common Mistakes
- Type-switching on a string, integer, or enum that represents a known set of types — use polymorphism instead.
- The same switch appearing in multiple places across the codebase — shotgun surgery.
- Not using match expressions in PHP 8 which at least provide exhaustiveness checking.
- Switch on type in service code when the decision should be in the domain object itself.
Code Examples
✗ Vulnerable
// Switch on type — must update for every new animal
function makeSound(string \$type): string {
switch (\$type) {
case 'dog': return 'Woof';
case 'cat': return 'Meow';
default: return '???';
}
}
✓ Fixed
// Polymorphism — each class knows its own behaviour
interface Animal { public function makeSound(): string; }
class Dog implements Animal { public function makeSound(): string { return 'Woof'; } }
class Cat implements Animal { public function makeSound(): string { return 'Meow'; } }
function play(Animal \$a): void { echo \$a->makeSound(); }
// Caller never changes when a new animal is added
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
22 Mar 2026
Views
23
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Amazonbot 7
Perplexity 5
Unknown AI 2
Ahrefs 2
Google 1
Also referenced
How they use it
crawler 17
Related categories
⚡
DEV INTEL
Tools & Severity
🟡 Medium
⚙ Fix effort: High
⚡ Quick Fix
A switch on a type field often means missing polymorphism — replace it with a Strategy pattern or a method on the entity itself; each case becomes a class with a shared interface
📦 Applies To
any
web
cli
queue-worker
🔗 Prerequisites
🔍 Detection Hints
switch($type) with many cases in multiple places; same switch logic duplicated in multiple methods; switch that grows every time a new type is added
Auto-detectable:
✓ Yes
phpmd
phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Medium
False Positives: Medium
✗ Manual fix
Fix: Medium
Context: Function
Tests: Update