Timothy Wittig

Home

Trick people into thinking you're a great developer with refactoring

Published Apr 25, 2019

Whenever I finish writing code, I’m never perfectly happy about it. It always feels like my initial design wasn’t right and that the resulting code could be better. And that makes sense when you think about it. As a developer, you’re at your most ignorant about an implementation when you start it. You haven’t made specific decisions about data models and code flow that uncover edge cases in the design (“Wait, what should happen when this input is null?”), bad assumptions about data structures (“Hmm, I guess this class isn’t used exactly the same in these two places…”), misjudgments about scope (“Oh whoops, I need to pass in this other object to do everything I need in this method”), and other realizations. I can address these things as I recognize them but the outcome is typically unsatisfying and kludgey. It’s not the caliber of code that I see written by talented and respected engineers.

Here’s the trick – admit that you’re not going to write top tier code in your first pass. Lock that idea into your head had as you start implementing your design. Am I duplicating code? That’s ok for now. Is this a candidate for a strategy pattern? Maybe, we’ll see. Does this class still have a single responsibility? Too soon to know for sure. I focus on acceptance criteria because understanding and achieving that is the biggest factor in eventually determine the best answer to those questions. I don’t ignore those questions; I defer them. I plan for refactoring so I can answer those questions with more knowledge e.g. it turns out I wasn’t duplicating code because the it diverged with further implementation and a template method was more appropriate. The result is code that’s a lot closer to what those talented engineers write.

Refactoring makes you look even smarter when applied to a legacy product. Every legacy code base I’ve worked in was notorious for being difficult to comprehend and safely modify. It meant that co-workers were all the more impressed when I made changes to it without breaking anything. Again the trick was refactoring. I invested early in making the code more comprehensible and testable and the result was faster, bug free changes.

Assuming I’ve sold you on the “why” and the “when” of refactoring, you’re probably now asking “how”. The answer is straightforward – read Refactoring: Improving the Design of Existing Code by Martin Fowler and Working Effectively with Legacy Code by Michael Feathers. Both of these books are exceedingly applicable and realistic. The authors have worked in some gnarly code and address the challenges that go beyond the code itself. I can’t recommend them enough.

It’s worth calling out that I’m not advocating that upfront design be abandoned or design patterns shouldn’t be applied. What I’m recommending is that you consider refactoring as an additional and potentially more productive means of improving your design and identifying where to apply patterns.