Recently, I attended a luncheon with a diverse group of people in the IT industry–coders, program managers, product managers, business analysts, and architects. The topic of the luncheon is not important, but at one point the conversation veered towards managing a product backlog, and how to prioritize items in the backlog. Two of the engineers in the crowd mentioned “refactoring” as an item that might go in the product backlog.
For those who don’t know, “refactoring” essentially is cleaning up an existing code base to enable changes to be made more efficiently, or to improve the performance of the existing system. Refactoring usually involves restructuring or rewriting portions of code which are convoluted, difficult to understand, poorly documented or unnecessarily complex. Refactoring, the engineers argued, is essential to add future features, so developers should be given time to “refactor” existing code– even if it is the only activity in that sprint or release.
Sorry, but I have to call B.S. here. Refactoring- standing on it’s own- adds no value, so it is not a feature, and should not be added to a product backlog. As a product manager, how am I supposed to sell a release which includes no new functionality, but has refactored code? Why would anyone want to buy such an upgrade? What does refactoring that provides no visible changes offer to a user? If it doesn’t add any business value, it isn’t worth doing.
Let me pause my rant for a moment to mention that developers who typically fight for periods of refactoring are usually the best developers on a team. They can’t stand seeing inefficient, messy, unmaintainable spaghetti code. I understand and appreciate their frustrations. There may be a secondary value to allowing refactoring to make it into release–to keep your developers happy, sane, and from leaving for greener pastures and that mythical software company where all code is documented meticulously and written as elegantly as possible. Besides that purely secondary value, I argue that refactoring is not worth doing as its own feature for the following reasons:
- It doesn’t accomplish a business goal: The goal of a software company is to sell working software. Refactoring doesn’t allow me to sell more software, unless there is something (an additional feature) I need to add to the software that requires refactoring.
- It obscures the “real” problem that is trying to be solved with refactoring: I’m hesitant to devote an entire sprint/release to “refactoring”, because as a user I don’t know what problems that will solve for me. If you tell me I can’t add the features in the next sprint because the code base is munged, then account for the time you have to “unmunge” (yes I just made up that word) the code into your estimate. Otherwise, what you’re doing is gold-plating, and unnecessary to delivering value.
- There is no traceability between “refactoring” and any discernible feature: This is related to the above points, but if I can’t trace what you’re refactoring to a requirement, then it’s gold-plating. There might be activities a development team needs to do in order to fulfill a requirement or fix a defect (e.g., “improve page response time to 2 seconds”), but those activities should trace to a requirement (has someone even asked that the page response be improved by 2 seconds? And if so, why?) You can’t predict every feature I’m going to ask for as a product manager, so you might be unnecessarily refactoring portions of the code base.
- Your work might be thrown away tomorrow: Suppose I relented and allowed the development team 3 months to refactor a messy code base, without adding new value/features. The following month, the CTO decides to change the platform completely and start (mostly) from scratch, perhaps for good reasons. Meanwhile, my users are stuck with a release that included refactored code instead of some valuable features until the new version on the new platform is released.
I want to reiterate that I don’t think that refactoring should never be done; only that it should never be done in a vacuum without any relationship to business value, solving a business problem, or satisfying a requirement. Hopefully, that will lead to fewer conversations about general refactoring, and more conversations about giving developers time to perform some housekeeping that delivers specific value linked to a requirement of the software.