Refactoring - UML

Refactoring[Fowler 99] is a structured, disciplined method to rewrite or restructure existing code without changing its external behavior, applying small transformation steps combined with re - executing tests each step. Continuously refactoring code is another XP practice and applicable to all iterative methods (including the UP).

The essence of refactoring is applying small behavior preserving transformations (each called a 'refactoring'), one at a time. After each transformation, the unit tests are re - executed to prove that the refactoring did not cause a regression (failure). Therefore, there's a relationship between refactoring and TDD - all those unit tests support the refactoring process.

Each refactoring is small, but a series of transformations - each followed by executing the unit tests again - can, of course, produce a major restructuring of the code and design (for the better), all the while ensuring the behavior remains the same.

What are the activities and goals refactoring? They are simply the activities and goals of good programming:

  1. remove duplicate code
  2. improve clarity
  3. make long methods shorter
  4. remove the use of hard - coded literal constants
  5. and more...

Code that's been well - refactored is short, tight, clear, and without duplication - it looks like the work of a master programmer. Code that doesn't have these qualities smells bad or has code smells. In other words, there is a poor design. Code smellsis a metaphor in refactoring - they are hints that something may be wrong in the code. The name code smell was chosen to suggest that when we look into the smelly code, it might turn out to be alright and not need improvement. That's in contrast to code stench - truly putrid code crying out for clean up! Some code smells include:

  • duplicated code
  • big method
  • class with many instance variables
  • class with lots of code
  • strikingly similar subclasses
  • little or no use of interfaces in the design
  • high coupling between many objects
  • and so many other ways bad code is written...

The remedy to smelly code are the refactorings. Like patterns, refactorings have names, such as Extract Method. There are about 100 named refactorings; here's a sample to get a sense of them:

Table

This example demonstrates the common Extract Method refactoring. Notice in the Figure listing that the takeTurn method in the Player class has an initial section of code that rolls the dice and calculates the total in a loop. This code is itself a distinct, cohesive unit of behavior; we can make the takeTurn method shorter, clearer, and better supporting High Cohesion by extracting that code into a private helper method called rollDice. Notice that the rollTotal value is required in takeTurn, so this helper method must return the rollTotal.

Figure 21.2 The takeTurn method before refactoring

Now here's the code after applying the Extract Method refactoring:

Figure 21.3 The code after refactoring with Extract Method

We will see in iteration - 2 that this rollDice helper method is not a great solution - the Pure Fabrication pattern will suggest an alternative that also preserves the Command - Query Separation Principle - but it suffices to illustrate the refactoring operation.

As a second short example, one of my favorite simple refactorings is Introduce Explaining Variable because it clarifies, simplifies, and reduces the need for comments. The listings in Figure illustrate.

Figure 21.4 Before introducing an explaining variable

Figure 21.5 After introducing an explaining variable

IDE Support for Refactoring

Most of the dominant IDEs include automated refactoring support. See Figures for an example in the Eclipse IDE of applying the Extract Method refactoring. The rollDice method is automatically generated, as is the call to it from the takeTurn method. Notice that the tool is smart enough to see the need to return the rollTotal variable. Nice!

All rights reserved © 2020 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

UML Topics