Refactoring-Improving the Design of Existing Code——学习笔记(4)
Chapter 9 Simplifying ConditionalExpressions
(1)Decompose Conditional
You have acomplicated conditional (if-then-else) statement. Extract methods from thecondition, the part, and else parts.
if (date.before(SUMMER_START)||date.after(SUMMER_END))
charge=quantity*_winterRate+_winterServiceCharge;
else charge=quantity * _summerRate
重构后:
if (notSummer(date))
charge=winterCharge(quantity);
else charge = summerCharge(quantity);
(2)Consolidate Conditional Expression
You have asequence of conditional tests with the same result. Combine them into a singleconditional expression and extract it.
double disabilityAmount() {
if(_seniority<2) return 0;
if(_monthsDisable>12) return 0;
if(_isPartTime) return 0;
//compute the disability amount
重构后:
double disabilityAmount() {
if(isNotEligibleForDisability()) return 0;
//compute the disability amount
(3)Consolidate Duplicate Conditional Fragments
The samefragment of code is in all branches of a conditional expression. Move itoutside of the expression.
if (isSpecialDeal()) {
total = price * 0.95;
send();
}
else {
total=price *0.98;
send();
}
重构后:
if(isSpecialDeal())
total = price*0.95;
else
total=price*0.98;
send();
(4)Remove Control Flag
You have avariable that is acting as a control flag for a series of Boolean expressions.Use a break or return instead.
(5)Replace Nested Conditional with Guard Glauses.
A method hasconditional behavior that does not make clear the normal path of execution. Useguard clauses for all the special cases.
double getPayAmount() {
double result;
if(_isDead) result = deadAmount();
else {
if(_isSeparated) result = separatedAmount();
else {
if(isRetired) result=retiredAmount();
else result = normalPayAmount();
}
}
return result;
}
重构后:
double getPayAmount() {
if(_isDead) return deadAmount();
if(_isSeparated) return separatedAmount();
if(_isRetired) return retiredAmount();
return normalPayAmount();
}
(6)Replace Conditional with Polymorphism
You have aconditional that chooses different behavior depending on the type of an object.Move each leg of the conditional to an overriding method in a subclass. Makethe original method abstract.
double getSpeed() {
switch(_type) {
case EUROPEAN:
return getBaseSpeed();
case AFRICAN:
return getBaseSpeed()-getLoadFactor()*_numberOfCoconuts;
case NOWEGIAN_BLUE:
return (_isNailed) ? 0:getBaseSpeed(_voltage);
}
throw new RuntimeException (“Should be unreachable”);
重构后:

(7)Introduce Null Object
You haverepeated checks for a null value. Replace the null value with a null object.
if (customer==null) plan = BillingPlan.basic();
else plan = customer.getPlan();
重构后:

(8)Introduce Assertion
A section ofcode assumes something about the state of the program. Make the assumptionexplicit with an assertion.
double getExpenseLimit() {
//should have either expense limit or a primary project
return (_expenseLimit != NULL_EXPENSE) ?
_expenseLimit:
_primaryProject.getMemberExpenseLimit();
}
重构后:
double getExpenseLimit() {
Assert.isTrue(_expenseLimit != NULL_EXPENSE||_primaryProject != null);
return (_expenseLimit != NULL_EXPENSE) ?
_expenseLimit:
_primaryProject.getMemberExpenseLimit();
}