# 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;
else {
if (_isSeparated) result = separatedAmount();
else {
if (_isRetried) result = retiredAmount();
else result = normalPayAmount();
};
}
return result;

~cpp
double getPayAmount() {
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