Monday, March 14, 2011

Refactoring Trick: Replacing a simple Value with a Value Object

I've been enjoying James Shore's Let's Play TDD. It's a fine way to introduce those who are new to the exact mechanics of TDD.

I wanted to share a trick that Shore uses in Episode 15: "Integrating TaxRate and InterestRate": it's the incremental introduction of a Value Object into a chunk of code that's already using the primitive value.

In this case, it's a pair of rates: a tax rate and an interest rate.

The trick he employs is to temporarily provide a casting method that exposes the encapsulated primitive. In this case, it's a rate. For example:

package com.jamesshore.finances;

public class InterestRate {
  final private double rate;

  public InterestRate(int rate) {
    this.rate = rate / 100.0; 
  }

  public int interestFor(int amount) {
    return (int) (amount * rate);
  }

  public int rate() {
    return (int) rate;
  }
} 

Now, everywhere else in the code where you WERE using an integer format of the interest rate, simply include an instance of this class and call rate(). Now you can run your tests to green again.

At this point, you can incrementally push through the use of the Value Object (here, InterestRate) until the back-cast (here, rate()) is not used anywhere. Nice.

I did a little research to see if this very trick is covered say in Martin Fowler's canonical work, Refactoring. While Fowler does catalog two refactorings in this area: "Replace Data Value with Object" and "Change Value to Reference", he does not mention this particular twist of wrist.

No comments:

Post a Comment