February 8, 2019•1,055 words
Recently, I read a thread on Twitter about the need for developers to learn the skills of refactoring. In that thread, Ron Jeffries, one of the founders of the Agile Manifesto, claims that without tools like refactoring, agile projects cannot work because they are inherently about being able to change fast, which is hard if your design doesn't allow this. Refactoring in turn makes sure your design incorporates the gained knowledge as you iterate. Or as Kent Beck puts it: First make the change easy, then make the easy change!
The interesting bit about this thread is actually one of the responses. It mentioned the book "The mythical man month" and how project managers and managers in general never seem to read it although they would often greatly benefit from doing so.
Spoiler alert: While it is definitely an interesting read, developers shouldn't blame project managers for not being able to refactor the codebase or get rid of technical debt.
Refactoring or more precisely the desire to refactor parts of a software can be a point of friction between developers and project managers. The reason being is that it is often considered a waste of time. When being asked for time to refactor some code, a manager might ask: "why should I pay you for something that doesn't make a difference to me?" To some degree, they are right. From the outside, it is often hard to notice that a refactoring happend. And that is good! After all, refactoring is changing the code without changing the functionality. This means we actually don't want the changes to be visible to the outside.
Why do we, as developers, then want to make those changes?
Software always operates on a model of the real world. Because of that, some things are left out and other's may be represented in a simplified manner. As our software grows and new features are added, there is a good chance that the old models no longer fit. For some time, we might be okay with working around that. But as time passes, those workarounds get more and more awkward until we reach the point where more drastic changes are needed.
If you've worked over a longer period of time on a single software, you have very likely witnessed such a situation. While remembering that experience, pause for a moment and ask yourself: who on the project was aware of these awkward things? There is a good chance it was only 1 or 2 developers on the team, maybe a 3rd one who fixed an urgent bug once because the other two were on vacation. However, I'll go ahead and claim that the project manager is very likely not aware of them. You might have told them but that doesn't mean they understand what or why things are awkward. Reason being is that they probably don't know how to code and thus simply have a hard time relating to this problem. They don't see the problem and that is fine. They have different responsibilities on the project and thus other problems to deal with. Problems you probably cannot relate to or don't want to deal with.
As a software developer, you are the one who is concerned with the software design. After all, you (or your colleagues) created it. If it has flaws, it is your problem. A flaw in the design doesn't mean you are a bad developer. It just means that the circumstances changed. What may have seemed like a good idea 3 months ago, can be totally invalid today. However, why concern someone else with that? Especially, why concern someone who is not an expert on this field like your project manager or a customer?
It is your job as a software developer to understand what the business requirements are and translate them into code1. Any abstraction, any trade-off you make as part of doing that is your business. If the requirements change, you change the code. If abstractions no longer fit, change them aswell. It is part of your daily work. You shouldn't ask for dedicated time to do refactoring. This will only make it appear as something optional where in reality it is not. Don't put refactoring on the backlog. Just do it as part of your daily work.
There is another side of the story though. Developers do enjoy a lot of trust. After all, unless you are a developer yourself and watching closely, how can you tell if someone is actually working while sitting at a computer? Not only that but if you are working, are you working on the most important thing right now? This is something that you as the developer have to evaluate.
- Is the gain of the refactoring worth the cost?
- How valuable is this other feature compared to the refactoring?
- Is creating an abstraction at this point worth the cost?
- Am I sure that I understand the problem domain well enough, to know that the abstraction makes sense?
Only you can evaluate the gain of a refactoring since you are the expert on that matter. A manager will have a hard time evaluating the gain, so all they see is the cost. On the other hand, developers might have a harder time to see the cost and/or evaluate the business value of a feature. The missing bits of information make an informed decision hard.
As often, the key thing again is communication. As a developer, you should thrive to understand the business problem you are trying to solve. This will allow you to get a feeling for the priority and value of the features. You should also try and judge as objectively as possible whether a refactoring is actually necessary. Sometimes, a piece of code might be annoying but at least, it is well encapsulated, meaning it is not in the way. Unless it is actually causing you problems, there is little need to spend time on it. In addition, try to take little steps and refactor things piece-by-piece instead of doing one of those giant PRs again. Big rewrites are often a bad idea.
However, the most important thing to remember is: refactoring is your business, your concern. Don't make it someone else's by asking for permission.
You are free to disagree with this definition. ↩