Refactoring is something that we often have to do when developing software. Therefore, we’ve to know about it.
In this article, we’ll look at the problems that we may run into when refactoring.
When we change an interface, this means that anything that implements the interface and anything that calls something that implements the interface will all have to change.
The whole point of having interfaces is so that we don’t have to worry about the underlying implementation of something.
There’re some changes that we can do for refactoring. Changing method names are OK since they can automatically be changed all at once.
However, if we’re changing an interface that’s already published, then we’ve to keep the new and the old version of the interface to avoid breaking any existing code.
If we change the signature of the function, then we either call the old function or the new function depending on which interface is used.
We should try to reference both interfaces to see if the code still works with both the old and new interfaces.
We can make the old interface deprecated so that we won’t introduce breaking changes but let the users of the old interface know that the old interface will be deprecated and be removed in the future.
Design Changes That Are Difficult to Refactor
There’re design changes that are hard to refactor.
This may mean that we have to design that part of the program from scratch and write clean code to clean up the code.
When Shouldn’t We Refactor?
There’re times that we shouldn’t refactor. We may have to write code from scratch if it’s such a mess that it’s impossible to refactor.
In that case, it might be easier to start from the beginning.
A clear sign that we should rewrite is when the current code isn’t working as expected. We may discover that it’s full of bugs that it’s impossible to stabilize.
The code has to work mostly correctly if we want to refactor.
We can also consider refactoring a large piece of code into components with strong encapsulate.
This way, we can refactor or rebuild one piece of the code at a time. Because of the loose coupling, changing the code would be much easier than if we e kept the existing code.
If we’re close to a deadline, then we shouldn’t refactor. Refactoring always has a chance of breaking code.
Unfinished refactoring is technical debt. Most companies need debt to function properly.
However, we shouldn’t let is go out of hand or the company will go broke.
We got to manage the debt by refactoring our code in the case of software development.
Once we delivered the code, then we can refactor.
Refactoring and Design
Refactoring and design fo together. We should design our code well from the get-go so we won’t have to refactor so much.
Refactoring after we designed our code badly isn’t the most efficient use of our time.
We all run into issues with bad code and after we work with designs that are bad.
Then we either have to do a lot of refactoring after or we’ve to rewrite the bad part from scratch.
Also, we shouldn’t build our software to be too flexible. Flexible solutions are harder to maintain than ones that aren’t flexible.
If we don’t need the flexibility, then we shouldn’t put it in.
Flexibility costs us more time to build as it adds complexity to our code.
This makes everyone frustrated.
Even if we don’t implement flexible solutions now, we can still make our code to add flexibility later easily if needed.
Refactoring can lead to simple designs without sacrificing flexibility.
The design process can be easier and less stressful since we don’t have to design for all the flexibility that we don’t need now.
We can always refactor our code to add the flexibility that we need easily.
Therefore, we should design code that can be refactored easily.
Problems that we run into including changing interfaces and adding flexibility.
Changing interfaces means changing the implementation of whatever that implements the interface and use them.
Therefore, we’ve to keep both the old and new interfaces and deprecate the old one to avoid changes in breaking people’s code.
Also, we’ve to design code to make them easy to refactor so we can add changes to them later.