Refactoring 2nd Ed - Reworking examples
(this is a note on my progress for the second edition of my refactoring book.)
As with last week, this week has seen me working on review comments so I can finalize the technical content of the book before starting the production process. I went through all the comments last week, doing all the easy ones that I could deal with in less than an hour or so. That left the complicated ones, which are pretty stressful to be working on at this late stage in the game, with a (admittedly, somewhat self-imposed) deadline staring at me.
At the heart of my work this week is reworking two examples. Both were ones where a couple of reviewers found difficult to follow, so I needed to figure out something that I think will be easier. This isn’t just about changing the prose text, it’s also about reworking the code. I find code examples to be one of the most difficult aspects of my writing. I try to create examples that are just complicated enough to show the main point, but no more complicated that that. They are still artificially simplistic - any realistic example is just too much for most readers to get their head around - but I want them to resonate with readers’ day-to-day experience. Today I spent most of the day coming up with an example that’s about fifty lines of code. I think it captures what I’m trying to say, but I’ll learn more as I carry out the refactoring I’m illustrating on this code and see how my prose works with it. I’m optimistic that it will work, but there’s still a fair bit of uncertainty.
The earlier example was particularly tricky as it was a section of a larger refactoring example, the future opening example of the book. This example divides into three phases, and reviewers indicated problems with the middle phase. I reworked the sequence of the refactorings, and hopefully things are much clearer now. Interestingly this refactoring centers around a refactoring (Split Phase) that I hadn’t written up before my first draft of the opening example. The essence of the change was to follow the now-written mechanics of this new refactoring, and I was happy to see that following these mechanics seemed to make it a good bit easier to do and understand. The mechanics sections in my book aren’t the only mechanics for a refactoring, and they can’t be the best for all contexts. My aim is that they should work pretty well, most of the time. So I was pleased that following them helped me through this example.
Reworking refactoring examples like this make me very familiar with git. I like to keep all my code examples “live”, so that I can change the code, run tests to ensure it still works, and mark sections of it to automatically flow into the book text. I’ve done this for many years with code examples, and it’s made life much easier. But doing this is tricky with refactoring, since I have a sequence of changes to the code. To cope with this I store the refactoring sequence in a git repository (necessarily a separate repo to the one that stores the book’s text) and capture the refactoring as a sequence of commits. I then import the code into the book text with tags that indicate the ref of the commit, and the name of the code fragment. When reworking a sequence of refactorings like this, I do a lot of cherry picking, where I make a change to commit master~7, then cherry pick all the refactoring changes I did since onto the changed commit. It’s awesome when it works well, and even when it doesn’t it’s far better than what I had to do with the first edition of the book.
I have one more week at my desk before I’d like to declare “done”. The target still seems plausible, although much will depend on how the fifty lines I wrote today works as I write about the refactoring steps that go with it.