The August 2002 Overload magazine prompted me to write this article. It's not really a book review and I would like to see some feedback on other people's opinions on both this book and the subject of refactorisation as a whole.
I noticed that the word 'refactoring' was used both by Jon Jagger (Section heading in 'even more Java Exceptions') and in a more detailed way by Allan Kelly (Philosophy of Extensible Software). The latter referenced this book which had also been recommended to me by a work colleague, so I decided to read it.
The book takes as its subject the process of improving codes internal structure/readability etc. without making any changes to the external working of the code. From a user's point of view, the refactoring process should have no effect. From the maintainer's point of view, this process should make the code easier to understand, debug and modify.
Although the book is nominally by Fowler, there are some major contributions made by Kent Beck and others. I was surprised how consistently the style was maintained throughout the book, which is written in a chatty, easy to read style. I found it generally both clear and easy to read.
The book attempts to cover a number of purposes:
- l explanation to the reader why refactorisation is a good thing to do
- l a 'catalogue of refactorisations' - a set of instructions of how to perform refactorisation.
- l a survey of refactorisation in the real world.
To be honest, I had problems with all of these sections.
Although I agree that there are circumstances when refactorisation might be a good idea, there were some things that I disagree on:
- l A solid unit test suite will make it safe to change code. If this were the case, code would never have bugs in it. Yeah, right. This hint is given: 'It is better to write and run incomplete tests than not to run complete tests'. True, I agree. However, it would be folly to rely on these incomplete tests to protect you against stupid errors introduced by your (functionally unnecessary) code changes.
- l If your manager/team leader does not believe in refactorisation, do it on your own initiative without telling what you are doing. Although this might be sometimes necessary it does seem dangerous to advocate it without major caveats. In particular, if you are going to put this refactored code through code review (as recommended by the book), howare you going to stop your team leader noticing the refactoring. What is his reaction likely to be when a 20 line code change has turned into a 200 line code change (sure, 180 lines are trivial changes, but the difference utility will still quote them). I have had an experience where a coder reordered a source file so that all the methods were in alphabetical order. The code review is non-trivial under such circumstances!
- l There seems to be a thread of 'good up-front design is not necessary, as we can always refactor the code afterwards to batter it into a good design'. This might be true at the micro-level of system design. I don't agree at higher levels.
A large part of the book consists of the refactoring catalogue. These are a set of instructions to be used to perform particular refactorisations (for example 'Replace Type Code with Subclass' which explains how a switch statement can be replaced with subclassing). This is written with a Java programmer in mind, although it is general enough to be generally applicable to C++ (for example). In general I found these recipes probably over simplistic (nothing there that I would not do instinctively, I think), while giving a false sense of dependability.
Things I didn't like (from a brief survey)
- l compile and test not being the last code change in at least one recipe (Inline Method).
- l In the recipe: 'Replace Type Code with Subclass' a C++ coder might forget to check that the class being subclassed has a virtual destructor. (Possibly not an issue to a Java programmer?)
- l there seems to be no acknowledgement of working in teams. A change to a method name might make sense to you, but might not be as clear to a colleague. (Or might just irritate the pants off them if they happen to have remembered the names of methods in particular classes).
Towards the end of the book, a chapter is devoted to the subject of why coders do not refactor. Interestingly, my concerns of whether unnecessary code changes can be made safely did surface. The solution here was an automated refactoring tool for Smalltalk. Apart from the fact that I wouldn't trust this any more than a coder (unexpected side-effects, timing issues, language peculiarities, subtle bugs in the tool) what does this say for Java refactorisation?
In summary, I found this an interesting book, with some good points and it was a useful exercise to read it. My main grouse was not in whether refactorisation is a 'good thing' or not (I believe that it has its place), but that I felt that it might encourage a 'gung-ho' attitude in a reader towards refactorisation, giving the impression that there are code changes that can be made purely mechanistically, without care, attention, planning and thought. Looking at Amazon's book reviews, I realise that it might be a rather a contrarian point of view to not love every paragraph of this book. I wonder what other people's opinions are?C ++