Luhn Module: Refactoring: Extract DigitDoubler class Part 1

To follow along, you can check out the luhn-extract-digit-doubler-class branch from the git repo:

$ git clone [email protected]:stephenaument/tactical-refactoring.git # If you haven't done this already
$ git checkout luhn-extract-digit-doubler-class


I’m going to apply the same treatment to the private double method and extract it to a new class, but I’m going to take a slightly different, tiny-step approach.

First, let’s make the extraction local to the private double method. We’ll write the code we wish we had and push the guts down to our new class.

I want the same convenience class method approach that we used before, so I’ll go ahead and start with that code.

Let’s call this class DigitDoubler.

I want the code to read as, DigitDoubler.double digit.

Define the class below.

Define the class method.

And transfer the contents directly from the private method.

And we’re green.

Now that we know this works as is and we have moved the details to a new class, let’s replace the call to the private method on line 36 with a call directly to our new class and its convenience method.

Notice, we can just prepend DigitDoubler to the existing call.

That passes, so we can delete our private method altogether.

Now that we have isolated the doubling to its own class, we should create a test and start covering the functionality we know is there.

It’s a complex algorithm, so we will have at least three cases.

First, a simple double.


Now, let’s test the case where a doubled digit is greater than 9.


Finally, we want to test that nil returns nil rather than throwing an error.

That works.

But by extracting our private method to its own class, we have exposed a new possibility. Somebody else might use this method and they might not pass nil or an Integer.

We can either do our best to make sure we have an integer, or we can let it raise an exception. Let’s be good citizens and at least try to convert what we have been given to an integer by calling Integer() with the input.

First, we’ll add a test that passes a number as a string.

It fails, so we need to make sure we normalize our input.

Great. We are green again.