4 Make type codes work

 

This chapter covers:

  • Eliminating early binding with Never use if with else and Never use switch
  • Removing if statements with Replace type code with classes and Push code into classes
  • Removing bad generalization with Specialize method
  • Preventing coupling with Only inherit from interfaces
  • Removing methods with Inline method and Try delete then compile

At the end of last chapter, we had just introduced a handleInput function that we could not use Extract method [P3.2.1] on because we do not want to break up the else if chain. Unfortunately, handleInput is not compliant with our fundamental Five lines [R3.1.1] rule, so we cannot leave it as is.

Here’s the function:

Listing 4.1. Initial
function handleInput(input: Input) {
  if (input === Input.LEFT)
    moveHorizontal(-1);
  else if (input === Input.RIGHT)
    moveHorizontal(1);
  else if (input === Input.UP)
    moveVertical(-1);
  else if (input === Input.DOWN)
    moveVertical(1);
}

4.1 Refactoring a simple if-statement

We are stuck. To show how we deal with else if chains like this, we start by introducing a new rule.

4.1.1 Rule: Never use if with else

Statement

Never use if with else, unless we are checking against a data type we do not control.

Explanation

4.1.2 Applying the rule

4.1.3 Refactoring pattern: Replace type code with classes

4.1.4 Pushing code into classes

4.1.5 Refactoring pattern: Push code into classes

4.1.6 Inlining a superfluous method

4.1.7 Refactoring pattern: Inline method

4.2 Refactoring a large if-statement

4.2.1 Removing generality

4.2.2 Refactoring pattern: Specialize method

4.2.3 The only switch allowed

4.2.4 Rule: Never use switch

4.2.5 Eliminating the if

4.3 Addressing code duplication