
This week I read a blog article from Martin Fowler’s blog titled “Refactoring: This Class is Too Large” by Clare Sudbury. Find that post here.
What was the blog about?
Sudbury walks us through how she would refactor a poorly-written (real-life example) codebase and the common mistakes people make when developing code that ultimately precipitate rounds of refactoring.
Why do we refactor?
Our code evolves. At first, as Sudbury puts it, what most people have are big “entrance halls” to their problems; big main methods and such where a jumble of not-necessarily related but nevertheless heavily coupled code sits together for the sake of convenience and because we have, at that point, only a shaky or infirm grasp of what architecture our code will have in the future. That’s fine–for a start, and for a time.
Problems arise when we keep trying to entertain in the “entrance hall”. We need to refactor in order for our structural conventions to even continue to make sense.
Why did I choose this article?
I need to be better and more strategic more about refactoring, and having a ton of visual references (the examples) paired with the reinforcements of best practices helps tremendously.
There are also other considerations we haven’t talked about in-class that Sudbury talks about in more detail, such as how to structure our refactors within a series of commits that make logical sense for anyone looking from the outside in, so her blog is doubly worth reading for those extra touches alone.
What are the steps to refactoring?
For the most part, these steps are well-founded in the context of our course and should be pretty easily understood in that sense. In short, though, we can think of refactoring out a method from a parent class as having six distinct steps.
- Organize methods and related code into distinct regions–more of a logistical than an architectural point, but keeps with what we’ve learned in this course. Code that changes together stays (and collapses) together.
- Verify dependencies and class relationships of the method to be refactored using diagrams or similar tools–again, tracks with what we’ve learned. This is exactly the use case of UML class and sequence diagrams.
- Clean-up methods that stay in the “entrance hall”–we’ll keep some parts of our method in our main class, but with appropriate changes, since methods that they might have invoked may now be sitting elsewhere.
- Create a new class to contain the refactored method and test it in the simplest terms possible (tiny steps principle).
- Build more test coverage for the new class (TDD).
- Move method(s) to the new class.
We repeat for as many methods with unique behaviors as there are in the code.
How does this relate to the course material?
We learned that, in the course of developing a problem, we might have code structures that become obsolesced or which are consolidated into others, i.e. composition. And we’ve done refactoring a little, as with the DuckSimulator code from one of our homeworks. But what we haven’t looked at is how to actually systemize this process of refactoring so that it becomes second-nature to us and the steps taken become intuitive rather than a feat of mental gymnastics. If we can’t conceptualize the process of refactoring as an organic evolution of our codebase, we are doomed to stay in cycles of bad code and refactoring, bad code and refactoring, etc. For my own sake and for that of my professional career, I’d better learn to refactor more.
It’s not just about making unit tests.
Kevin N.
From the blog CS@Worcester – Kevin D. Nguyen by Kevin Nguyen and used with permission of the author. All other rights reserved by the author.



