No older revisions available
No older revisions available
1.1. Decompose Conditional ¶
- You have a complicated conditional (if-then-else) statement.
Extract methods from the condition, then part, and else parts.
~cpp
if (data.before( SUMMER_START ) || data.after(SUMMER_END) )
charge = quantity * _winterRate + _winterServeceCharge;
else charge = quantity * _summerRate;
~cpp
if (notSummer(date))
charge = winterCharge(quantity);
else charge = summerCharge(quatity);
1.2. Consolidate Conditional Expression ¶
- You have a sequence of conditional tests with the same result.
Combine them into a single conditional expression and extract it.
~cpp
double disabilityAmount() {
if (_seniority < 2) return 0;
if ( _monthsDisabled > 12) return 0;
if ( _isPartTime) return 0;
// compute the disability amount
~cpp
double disabilityAmount() {
if( isNotEligableForDisability()) return 0;
// compute the disability amount;
1.3. Consolidate Duplicate Conditional Fragments ¶
- The same fragment of code is in all branches of a conditional expression.
Move it outside of the expression.
~cpp
if (isSpecialDeal()){
total = price * 0.95;
send();
}
else {
total = price * 0.98;
send();
}
~cpp
if (isSpecialDeal())
total = price * 0.95
else
total = price * 0.98;
send();
1.4. Replace Nested Conditional with Guard Clauses ¶
- A method has conditional behavior that does not make clear the normal path of execution
Use guard clauses for all the special cases.
~cpp
double getPayAmount(){
double result;
if( _isDead) result = deadAmount();
else {
if (_isSeparated) result = separatedAmount();
else {
if (_isRetried) result = retiredAmount();
else result = normalPayAmount();
};
}
return result;
~cpp
double getPayAmount() {
if (_isDead) return deadAmount();
if (_isSeparated) return separatedAmount();
if (_isRetried) return retiredAmount();
return normalPayAmount();
1.5. Replace Conditional with Polymorphism ¶
- You have a conditional that chooses different behavior depending on the type of and object
Move each leg of the conditional to an overriding method in a subclass. Make the orginal method abstract.
~cpp
double getSpeed() {
switch (_type) {
case EUROPEAN:
return getBaseSpeed();
case AFRICAN:
return getBaseSpeed() - getLoadFactor() * _numberofCoconuts;
case NORWEGIAN_BLUE:
return (_isNailed) ? 0 : getBaseSpeed(_voltage);
}
throw new RuntimeException ("Should be unreachable");
}
~cpp
┌─────┐
│ Bird │
├─────┤
│getSpeed │
└─────┘
△
│
┌───────┼─────────┐
│ │ │
┌──┴──┐ ┌──┴──┐ ┌────┴──┐
│European| │ │African │ │Norwegian Blue│
├─────┤ ├─────┤ ├───────┤
│getSpeed │ │getSpeed │ │getSpeed │
└─────┘ └─────┘ └───────┘
1.6. Introduce Null Object ¶
- You have repeated checks for a null value
Replace the null value with a null object.
~cpp
if (customer == null) plan = BillingPlan.basic();
else plan = customer.getPlan();
~cpp
┌───────┐
│ Cutomer │
├───────┤
│getPlan │
└───────┘
△
│
┌───┴───┐
│Null Customer │
├───────┤
│getPlan │
└───────┘
1.7. Introduce Assertion ¶
- A section of code assumes something about the state of the program.
Make the assumption explicit with an assertion.
~cpp
double getExpenseLimit() {
//should have eigher expense limit or a primary project
return (_expenseLimit != NULL_EXPENSE)?
_expenseLimit:
_primaryProject.getMemberExpenseLimit();
}
~cpp
double getExpenseLimit() {
Assert.isTrue( _expenseLimit != NULL_EXPENSE || _primaryProject != null );
return (_expenseLimit != NULL_EXPENSE)?
_expenseLimit:
_primaryProject.getMemberExpenseLimit();
Refactoring










