Conditional Simplification Strategy
by @quochungto
Select and apply the correct refactoring for complex or tangled conditional logic. Use when: a method has a complicated if-then-else that obscures why branch...
Example 1: Choosing Between Polymorphism and Explicit Methods
Scenario: A Shape class has this method:
double area(String shapeType) {
if (shapeType.equals("circle")) return Math.PI * _radius * _radius;
if (shapeType.equals("rectangle")) return _width * _height;
if (shapeType.equals("triangle")) return 0.5 * _base * _height;
throw new RuntimeException("Unknown shape");
}
Two questions determine the refactoring:
1. Does shapeType vary at runtime (computed value), or is it always a literal at call sites?
2. Are new shape types expected?
If both answers are yes: Pattern 6 β Replace Conditional with Polymorphism. Create Circle, Rectangle, Triangle subclasses; each implements area(). Adding Pentagon = adding a class.
If the type set is stable and callers always pass literals: Pattern 7 β Replace Parameter with Explicit Methods. Create circleArea(), rectangleArea(), triangleArea() methods. Simpler, statically checkable, no hierarchy overhead.
Decision rule: When types will grow or the conditional appears in multiple places β polymorphism. When types are fixed, the conditional is in one place, and callers always pass constants β explicit methods.
Example 2: Identifying a Null Object Opportunity
Scenario: Three separate methods in client code contain:
if (customer == null) plan = BillingPlan.basic();
else plan = customer.getPlan();if (customer == null) name = "occupant";
else name = customer.getName();
if (customer == null) weeksDelinquent = 0;
else weeksDelinquent = customer.getHistory().getWeeksDelinquentInLastYear();
Classification: Pattern 8 β the same object (customer) is null-checked in multiple clients, each providing a sensible default.
Apply Introduce Null Object:
class NullCustomer extends Customer {
public boolean isNull() { return true; }
public String getName() { return "occupant"; }
public BillingPlan getPlan() { return BillingPlan.basic(); }
public PaymentHistory getHistory() { return PaymentHistory.newNull(); }
}
// class NullPaymentHistory: getWeeksDelinquentInLastYear() returns 0// Site returns NullCustomer instead of null:
Customer getCustomer() {
return (_customer == null) ? Customer.newNull() : _customer;
}
// Clients become:
plan = customer.getPlan();
name = customer.getName();
weeksDelinquent = customer.getHistory().getWeeksDelinquentInLastYear();
The three conditional blocks disappear. Note that null objects often return other null objects β NullCustomer.getHistory() returns NullPaymentHistory, which itself returns sensible defaults.
clawhub install bookforge-conditional-simplification-strategy