Makers Academy Day 18

Charlotte Fereday
4 min readMay 29, 2017

--

A few days ago I wrote about the Takeaway weekend challenge and how I had inadvertently written a program with a monolithic Takeaway class that had far too much responsibility. Here’s an overview of my approach with the class extraction, how the program has changed and what I’ve learnt.

Class extraction and refactoring

Firstly for anyone who is also on an extraction mission as I was, I recommend reading as much Sandi Metz as possible. Her book Practical Object Orientated Design in Ruby for example has been invaluable. As I was preparing to refactor my code, I came across a post that succinctly summarised a few of her rules for developers from a podcast series she had done for beginners. These were the rules I had broken:

1. Classes can be no longer than one hundred lines of code.

2. Methods can be no longer than five lines of code. — Caleb Thompson, Sandi Metzs’ Rules for Developers

As I had built a takeaway ordering interface in the command line, one of my main struggles was dealing with input and output in my unit tests. I had an especially tricky while loop that dealt with this and had spent a lot of time when I first wrote the program working out how to make my tests pass.

As I came back to work on the project I considered scrapping what I had written and starting again. I was thinking back to the Introduction to Corey Haines Understanding the Four Rules of Simple Design, and how being forced to begin again can often result in better code and force you to approach a problem in a new way:

Most people will begin working on a problem in the way they are comfortable. The constraints are there to remove the ability to code in a familiar, comfortable way…The separation of identity from code frees them to experiment with new ideas. When value isn’t tied to amount (or quality) of code, they can more readily accept that an attempt isn’t working and discard it. — Corey Haines Understanding the Four Rules of Simple Design

My approach

In the end I decided to refactor what I had to get more comfortable with class extraction. My approach was to zoom in on one step at a time. This focus of attention helped me to not be overwhelmed by the task at hand. Here’s a break down of how I did my extraction:

Display

I had already created the Display class, but wasn’t making proper use of it. In fact it had just one method in it, which served a purpose, but it meant that a lot of its behaviour was being pushed on to Takeaway and was one of the main reasons why the Takeaway class was so long.

Display class on the right and its tests on the left

The first thing I did was to find all puts and extract them to the Display class. This had a lot of benefits for me gaining clarity over the program. It decluttered the Takeaway class by about 50 lines, by reducing methods to a single responsibility. It became obvious that many methods did more than one thing, and one of the reasons for this was that they were displaying output. I renamed the methods and some variables to make it explicit what these objects did in the context of the behaviour of the class.

The other benefit was in my tests. As all of them now had an standard output as their test, I was more easily able to spot the pattern for how to correctly deal with this consistently.

Menu

The second thing I did was to extract some responsibility from Takeaway to Menu. There were actually already some methods such as ‘extract_starters’ which explicitly indicated from their name that their behaviour that they belonged to another class.

Extract of my new Menu class

It felt a bit like spring cleaning as again I took about 37 lines of code from Takeaway to Menu. This gave clarity to me and other developers who might come to the program on the differences between them. With the view, to paraphrase Kent Beck, to make my program be the expression of requirements in code.

Carrying out this extraction and refactoring process helping me to gain a lot of clarity. As I looked at my Takeaway class it was now clear that all of the methods in there did belong to the behaviour of the class. Thanks to the refactoring my methods and class as a whole were significantly shorter and easier to understand. It was also a positive experience in terms of getting over the fear of class extraction. Seeing the process as a small step by step puzzle, rather than a huge mythical beast! I applied a pragmatic mindset that forced me to only deal with one thing at a time.

Going ahead I’d like to ensure that “the almost continuous decisions made around things such as naming variables and extracting methods” ( Corey Haines Understanding the Four Rules of Simple Design) is a practice that I integrate religiously from the start of the project — rather than at the end.

I’d also like to experiment with the more extreme approach described by Corey Haines for a kata, to force myself to identify less personally with the code, and try new ways of tackling a problem that are out of my comfort zone.

--

--

Charlotte Fereday

Full stack dev @tes_engineering Security team. Proud alumni of @thoughtworks @CodeFirstGirls @makersacademy alumni 👨‍🎓