U E D R , A S I H C RSS

Refactoring/Simplifying Conditional Expressions

1. Chapter 9 Simplifying Conditional Expressions

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
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:27:53
Processing time 0.0148 sec