As software products evolve and grow, code gets harder to maintain and extend and if you have dealt with turnover in resources, you end up with a range of coding practices and quality. It is common to reach a point when it feels like refactoring will make more sense than trying to develop on top of existing code.
Developers tend to have strong views on this. Some (type A) are so convinced about the terrible quality of work by other developers that they want to refactor everything they touch. Some (type B) always take the risk-averse approach of making the least possible modifications that will complete their task. I have come across very few (type C) who approach it as a balancing act of optimizing while managing risk and these are ones who should be nurtured as future managers.
In a typical software development team, you will probably have personalities spanning the spectrum between these types. So as a manager, how do you decide when to refactor and when to avoid it?
The opportunity to optimize is best when you are touching a component and you can demonstrate a clear and obvious benefit to refactoring it. I will not delve into this point since it is subjective and depends much on code quality, developer experience, and testing capabilities. However, there are some circumstances when it is wise to avoid refactoring however appealing the opportunity.
1) Do not refactor when deadlines are extremely tight. Your developers are in stress to get things built or fixed. It is unrealistic to expect developers to optimize legacy code under high-pressure situations with any predictable level of quality. Even if your type A developers are convinced they can do it, resist the temptation and make them stick to the specific update or fix related task. Minimize the test scope.
2) Do not refactor a component that is unrelated to the features or fixes to implement. It makes no sense to expand the test scope of a project or task schedule just because you have spare capacity. Taking on this kind of risk will usually lead you to shoot yourself in the foot. If your developers have time on their hand, have them branch out the code and refactor for later use but don’t pull it into the trunk until that component is actually in play.
3) Do not refactor if that is the only thing you are doing during the scope of a release schedule. This is a bit counter-intuitive. You would think that having no other priority should give you the leeway to make improvements. The problem is that you are creating an impact during a period of quiet without enhancing business objectives. Instead, pick up a backlogged feature enhancement associated with the component you want to refactor and do these together. You achieve your desire to optimize code along with a proactive contribution to the business. A caveat to this point is if the refactoring is part of an architectural upgrade, which in itself should be a major business objective.
4) Do not refactor when the developer cannot explain their solution in clear and unambiguous terms. This may be an indication that the developer is unable to conceptualize or dissect the code into logically equivalent parts, or lacks the skills to analyze and propose optimized solutions. Get a second opinion. If you are in touch with the code, jump in and review it yourself. Either way, avoid having a developer refactor fully functional code if you are not confident they know what they are doing.
5) Do not refactor unless you have clarity that the optimization will achieve some business, architectural, standardization, performance, quality, or maintenance objective. This may not sound like a critical factor for seemingly small instances of refactoring. However, as a manager it is to your benefit to treat each instance as critical. Develop metrics and/or defendable rationale to decide whether it is worth expending your resources on refactoring and how it will contribute directly or indirectly to the bottom line.
Refactoring needs to be continuous improvement activity. Treating it as a distinct set of tasks can often make it difficult to schedule against competing tasks for new development, increase the risks of implementation, and eventually it falls off the priority list altogether. As in all cases, trust your instincts and experience.