Excessive Branching
Description
What does it look like?
- Excessive use of
if
/else if
/switch
makes the code hard to read - Logic for handling conditions is duplicated in multiple places
- As conditions increase, it becomes a breeding ground for bugs and decreases maintainability
Why is it a problem?
- Requires reviewing all conditions during modifications
- Single functions or classes become bloated with responsibility
- Difficult to unit test due to tightly coupled conditional logic
- Hard to extend (violates the Open/Closed Principle)
Bad Example of the Anti-pattern
- TypeScript
- PHP
- Python
function calculatePrice(userType: string, basePrice: number): number {
if (userType === "student") {
return basePrice * 0.8;
} else if (userType === "member") {
return basePrice * 0.9;
} else if (userType === "vip") {
return basePrice * 0.7;
} else {
return basePrice;
}
}
<?php
function calculatePrice(string $userType, float $basePrice): float {
if ($userType === "student") {
return $basePrice * 0.8;
} elseif ($userType === "member") {
return $basePrice * 0.9;
} elseif ($userType === "vip") {
return $basePrice * 0.7;
} else {
return $basePrice;
}
}
// 利用例
echo calculatePrice("student", 1000) . PHP_EOL; // 800
def calculate_price(user_type: str, base_price: float) -> float:
if user_type == "student":
return base_price * 0.8
elif user_type == "member":
return base_price * 0.9
elif user_type == "vip":
return base_price * 0.7
else:
return base_price
# 利用例
print(calculate_price("student", 1000)) # 800
Issues:
- As
if/else
blocks accumulate, readability, testability, and the risk of bugs increase - Every time a new
userType
is introduced, the function body must be edited—making safe extension difficult - Discount logic is embedded directly, making it hard to reuse or centralize
Refactoring by Pattern
Design patterns that can address this
Pattern | Overview | Main Refactoring Approach |
---|---|---|
Strategy | Extract conditional behavior | Allows behavior to be swapped at runtime |
State | Map each state to its own behavior | Let state objects encapsulate condition logic |
Command | Encapsulate each condition as a command | Enables recording and undoing actions |
Chain of Responsibility | Pass responsibility through a chain | Express conditions as a natural flow |
Interpreter | Parse and evaluate structured rules | Separate complex condition logic as a domain grammar |