Final considerations

Using TDD, we got a class with a constructor, five public methods, and six private methods. In general, all methods look pretty simple and easy to understand. In this approach, we also got a big method to check winner conditions: checkWinner. The advantage is that with this approach we got a bunch of useful tests to guarantee that future modifications do not alter the behavior of the method accidentally, allowing for the introduction of new changes painlessly. Code coverage wasn't the goal, but we got a really high percentage.

Additionally, for testing purposes, we refactored the constructor of the class to accept the output channel as a parameter (dependency injection). If we need to modify the way the game status is printed, it will be easier that way than replacing all the uses in the traditional approach. Hence, it is more extensible. In the test-last approach, we have been abusing the System.println method and it will be really tedious task if we decide to change all the occurrences for any other thing.

In large projects, when you detect that a great number of tests must be created for a single class, this enables you to split the class following the Single Responsibility Principle. As the output printing was delegated to an external class passed in a parameter in initialization, a more elegant solution would be to create a class with high-level printing methods. That would keep the printing logic separated from the game logic. Like the huge code coverage shown in the following image, these are a few examples of the benefits of good design using TDD:

The code of this approach is available at https://bitbucket.org/vfarcic/tdd-java-ch05-design.git.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.226.255