Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Refactoring/SimplifyingConditionalExpressions: Difference between revisions

From ZeroWiki
imported>Unknown
No edit summary
 
(Repair batch-0003 pages from live compare)
 
(One intermediate revision by the same user not shown)
Line 2: Line 2:
= Chapter 9 Simplifying Conditional Expressions =
= Chapter 9 Simplifying Conditional Expressions =
== Decompose Conditional ==
== Decompose Conditional ==
* You have a complicated conditional (if-then-else) statement. ''Extract methods from the condition, then part, and else parts.''
* You have a complicated conditional (if-then-else) statement. <br /> ''Extract methods from the condition, then part, and else parts.''
     if (data.before( SUMMER_START ) || data.after(SUMMER_END) )
     if (data.before( SUMMER_START ) || data.after(SUMMER_END) )
         charge = quantity * _winterRate + _winterServeceCharge;
         charge = quantity * _winterRate + _winterServeceCharge;
Line 11: Line 11:
     else charge = summerCharge(quatity);
     else charge = summerCharge(quatity);
== Consolidate Conditional Expression ==
== Consolidate Conditional Expression ==
* You have a sequence of conditional tests with the same result. ''Combine them into a single conditional expression and extract it.''
* You have a sequence of conditional tests with the same result. <br />''Combine them into a single conditional expression and extract it.''
     double disabilityAmount() {
     double disabilityAmount() {
         if (_seniority &lt; 2) return 0;
         if (_seniority &lt; 2) return 0;
Line 21: Line 21:
         // compute the disability amount;
         // compute the disability amount;
== Consolidate Duplicate Conditional Fragments ==
== Consolidate Duplicate Conditional Fragments ==
* The same fragment of code is in all branches of a conditional expression. ''Move it outside of the expression.''
* The same fragment of code is in all branches of a conditional expression. <br />''Move it outside of the expression.''
  if (isSpecialDeal()){
  if (isSpecialDeal()){
     total = price * 0.95;
     total = price * 0.95;
Line 36: Line 36:
  send();
  send();
== Replace Nested Conditional with Guard Clauses ==
== 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.''
* A method has conditional behavior that does not make clear the normal path of execution <br /> ''Use guard clauses for all the special cases.''
  double getPayAmount(){
  double getPayAmount(){
     double result;
     double result;
Line 55: Line 55:
     return normalPayAmount();
     return normalPayAmount();
== Replace Conditional with Polymorphism ==
== 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.''
* You have a conditional that chooses different behavior depending on the type of and object <br /> ''Move each leg of the conditional to an overriding method in a subclass. Make the orginal method abstract.''
     double getSpeed() {
     double getSpeed() {
         switch (_type) {
         switch (_type) {
Line 84: Line 84:


== Introduce Null Object ==
== Introduce Null Object ==
* You have repeated checks for a null value ''Replace the null value with a null object.''
* You have repeated checks for a null value<br /> ''Replace the null value with a null object.''
     if (customer == null) plan = BillingPlan.basic();
     if (customer == null) plan = BillingPlan.basic();
     else plan = customer.getPlan();
     else plan = customer.getPlan();
Line 101: Line 101:


== Introduce Assertion ==
== Introduce Assertion ==
* A section of code assumes something about the state of the program. ''Make the assumption explicit with an assertion.''
* A section of code assumes something about the state of the program. <br />''Make the assumption explicit with an assertion.''
     double getExpenseLimit() {
     double getExpenseLimit() {
         //should have eigher expense limit or a primary project
         //should have eigher expense limit or a primary project
Line 114: Line 114:
                 _primaryProject.getMemberExpenseLimit();
                 _primaryProject.getMemberExpenseLimit();
----
----
[[Refactoring]]
Refactoring
 

Latest revision as of 00:29, 27 March 2026

Chapter 9 Simplifying Conditional Expressions

Decompose Conditional

  • You have a complicated conditional (if-then-else) statement.
    Extract methods from the condition, then part, and else parts.
    if (data.before( SUMMER_START ) || data.after(SUMMER_END) )
        charge = quantity * _winterRate + _winterServeceCharge;
    else charge = quantity * _summerRate;
    if (notSummer(date))
        charge = winterCharge(quantity);
    else charge = summerCharge(quatity);

Consolidate Conditional Expression

  • You have a sequence of conditional tests with the same result.
    Combine them into a single conditional expression and extract it.
    double disabilityAmount() {
        if (_seniority < 2) return 0;
        if ( _monthsDisabled > 12) return 0;
        if ( _isPartTime) return 0;
        // compute the disability amount
    double disabilityAmount() {
        if( isNotEligableForDisability()) return 0;
        // compute the disability amount;

Consolidate Duplicate Conditional Fragments

  • The same fragment of code is in all branches of a conditional expression.
    Move it outside 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();

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.
double getPayAmount(){
    double result;
    if( _isDead) result = deadAmount();
    else {
        if (_isSeparated) result = separatedAmount();
        else {
            if (_isRetried) result = retiredAmount();
            else result = normalPayAmount();
        };
    }
    return result;
double getPayAmount() {
    if (_isDead) return deadAmount();
    if (_isSeparated) return separatedAmount();
    if (_isRetried) return retiredAmount();
    return normalPayAmount();

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.
    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");
    }
                ┌─────┐
                │  Bird    │
                ├─────┤
                │getSpeed  │
                └─────┘
                      △
                      │
      ┌───────┼─────────┐
      │              │                  │
┌──┴──┐  ┌──┴──┐  ┌────┴──┐
│European| │  │African   │  │Norwegian Blue│
├─────┤  ├─────┤  ├───────┤
│getSpeed  │  │getSpeed  │  │getSpeed      │
└─────┘  └─────┘  └───────┘

Introduce Null Object

  • You have repeated checks for a null value
    Replace the null value with a null object.
    if (customer == null) plan = BillingPlan.basic();
    else plan = customer.getPlan();
          ┌───────┐
          │  Cutomer     │
          ├───────┤
          │getPlan       │
          └───────┘
                  △
                  │
          ┌───┴───┐
          │Null Customer │
          ├───────┤
          │getPlan       │
          └───────┘                

Introduce Assertion

  • A section of code assumes something about the state of the program.
    Make the assumption explicit with an assertion.
    double getExpenseLimit() {
        //should have eigher 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();

Refactoring