Refactoring code vs Rewrite of code


Should you refactor existing code or rewrite?

A difficult decision to make when confronted with software problems

Intro

Recent history and experience teaches us that almost all software will build up technical dept over time due to inexperienced programmers, bad or neglected regular maintenance, pressing deadlines, unwanted but expensive features, dead code never removed, laws and regulations and many other reasons.

So what to do? Do we refactor the existing code to manageable levels or do we rewrite everything? Often it seems an easy choice to make, but experience learns that most of the time these choices have far-reaching effects and entail much more than the simple choice to do the one or the other. Should it be a choice for either one or can there be a combination of the two? can we prevent the build up of technical dept completely?

In this blog post I will try to dive a bit into what the choices are and what the possible Pro’s and Cons and possible consequences are of the choices.

Both options have their advantages and disadvantages. Rewriting code makes it possible to completely change the architectural setup of a system, but can lead to breaking the product if not done right. Refactoring can keep the code manageable without having to change everything, but may not make it easy to work with emerging technologies or languages.

Refactoring and rewriting code are not enemies of each other, and you should never choose on over the other for everything. Often it can be a combination of the two and the circumstances of the code, technology and the team should determine what will be done.

Let’s look at some of the Pro’s and Con’s of refactoring and rewriting code and try to see of we can distill some guidelines from them

Refactoring Code

Code refactoring is the process of restructuring existing code - changing the factoring - without changing its
external behavior. Refactoring is intended to improve the design, structure and/or implementation of the software,
while preserving its functionality.
– wikipedia

So refactoring is always done on existing code, but that does not mean it needs to be old code. Refactoring can be done on code that has just been written but can be improved on. Extreme programming actually advocates this and stresses continues refactoring.

Refactoring the code is mainly for the developers not necessarily for the compiler. Refactoring is to make the code easier to understand by other developers and to make it more trustworthy because of it.

Some reasons to choose refactoring:

  • Reinventing something that already exists is useless
  • No information available about the feature(s)
  • No information about requirements
  • The user experience is not impacted
  • There is no guarantee that rewriting will improve the quality
  • The current code is already “proven”. At least in production.

Advantages of refactoring

  • Improved readability. Refactoring should always make the code more readable for other developers.
  • Reduced complexity. A good reason to refactor is to reduce complexity while maintaining the functionality.
  • Improved maintainability. When you achieve the above two the maintainability will immediately go up.
  • Improved extensibility. When trust in the software grows it is less of an obstacle to overcome to make changes.
  • Refactoring can be done at any time. You can do a major overhaul of a piece of software or just refactor the small part of the code a developer is working on at the time. Refactoring does not have to cost much if it is part of the daily life of a developer.
  • Refactoring can be done on any type of codebase. It does not matter if it is a Monolithic system or a distributed system.
  • The code is already in production and the way to production is already known. You are improving “proven” code.

Disadvantages of refactoring

  • Refactoring does not fix architectural problems already in the software. It can improve its functionality within that architecture but not change it. e.g. Code written in COBOL will still be written in COBOL even when refactoring.
  • In order to effectively refactor code you need to be able to trust that you will not change the functionality of the code during your refactoring. Trust can only be gained by extensive unit testing and if that is not part of the normal flow of development this can be a major investment.
  • Refactoring is as strong as the skill of the developer. It requires skill and courage and can look daunting to less experienced programmers. Less experienced programmers may even experience it as a waste of their time as “the code already works right?”.

So refactoring is very useful in many ways, but requires discipline, skill and an extensive test suite. When happy with architectural choices made it is a great way to keep the code up to par and maintainable. When architectural changes are required by whatever reason it is time to start looking at rewriting the code.

Rewriting code

Rewriting code is exactly that. Instead of trying to better the existing code we can choose to write new code. Unlike refactoring, code rewrites seem straight forward. The developer just starts over right? Spoiler alert… it isn’t! You are not actually starting a greenfield project, but are developing a new system based on strict requirements. Requirements not always clear but still strict as you already have a customer base.

There are many reasons to want to rewrite code.

Good reasons:

  • The language must be changed
  • The source code is not available (anymore)
  • The code is difficult to understand
  • The source code has become a problem
  • New technologies are wanted or needed
  • A new platform is wanted or needed
  • Debugging has become difficult
  • The code has build a large technical depth
  • To stimulate your developers group
  • Copyrights or licensing issues
  • It does not compile anymore
  • Architecture needs to change significantly
  • Resources are very hard to find

Bad reasons:

  • Dislike of how the code looks
  • Laziness
  • Not written by “me” (Not invented here problem)
  • Application is too slow
  • Lack of respect for the former creators
  • Ugliness

To successfully rewrite software, you need to maintain the current production software and write the new system at the same time. So that means two teams at least. One to write the new system and one to maintain the current one. Effectively duplicating a lot of resources and that is not all! The current (old) production system will need to keep working. Sometimes for years to come depending on the size of the system. It may need to even bring out new features due to e.g. new laws or prior agreements with customers. The rewrite team must constantly adjust to these changes too. With the rewrite of the system come new feature requests.

Advantages of rewriting code

  • You can utilise the latest and greatest technologies, language(s) and frameworks while rewriting the code. It opens the way to the newest platforms like cloud, web and mobile and that opens the way to new markets and customers.
  • It eliminates the need to try to fit unfit code unto these new technologies and needs.
  • A new start also gives developers the change to do it right from the start and write their code with maintainability, readability and testability in mind. It makes it much easier to be proud of your work and stay proud.
  • Starting new makes it possible to review important decisions from the past. It makes it way easier to adapt to new development approaches. It bridges the gap between legacy and new technologies.
  • Avoiding past mistakes
  • Fresh application design

Disadvantages of rewriting code

  • Effort! Rewriting code takes time and effort and lots of it. Rewriting code is not the same as adding new features. You may have to invest years to be at the same level as you were with the old code with the one distinction that you are now ready for the future. It is very difficult to explain to management that you need to “fix” a working clock. Management must be very committed to make this work. They must make this decision being well-informed. Rewriting often takes much longer than expected.
  • You may need to write temporary code to sync production to the new system constantly while the old system is still the leading software. You may need to write code that validates these syncs. You may want to shadow run in production for a time to gain confidence and trust. A lot of extra effort for no direct customer value.
  • As you are probably moving to more modern technologies and therefore changing a lot of the requirements, your customers also need to change with you in this process and probably be made part of the change process. They also need to know what the effort entails. Involving customers will not make this process easier but is probably unavoidable. This requires careful management of expectations and may be a real bottleneck. New suggest better, but that might not be the case at first. Stakeholder expectation management is needed. Return of investment is not always clearly evident.
  • The gap between the team maintaining the production software (legacy) and the team building the new system can grow and that can cause problems on more personal levels like for example motivation. It is important to make the maintenance team an integral part of the migration. They can, sometimes rightly so, feel threatened.
  • Old code will probably become even uglier. Refactoring of the code is stopped and only minimal effort is put into keeping it running just long enough for the new code to replace it even though this may take years. That makes rewriting code a real commitment. Prematurely stopping this process, for any reason, can be more costly than imagined, because during this period the actual production code can have deteriorated a lot.
  • It might therefore be necessary to do more than only keep it running if you want to keep your competitiveness on the market. If you do not, you may give your competitors a free head start.
  • A rewrite may not guarantee great new code. Often a completely new skillset is required for the new codebase. A skillset that may not be present within the company. A skill that needs to be learned. How will we learn? Is a course enough or do you need experienced senior developers already versed in these new technologies? Is that a possibility? If this part is not done right you will start rebuilding your technical dept immediately and have the same problems again soon. Often with disastrous effect even before the rewrite has completed.
  • Risk of missing features. Documentation is often unmaintained and therefore untrustworthy, but you are actually rewriting a system with strict requirements for your existing customers. The production (old) code may therefore be the only proven source of knowledge left of the system other than the developers working on it. It is very possible to need to dive into the code on a very detailed level to distil the information needed to be able to rewrite it in the new form. When a system has existed for quite a few year already there are guaranteed to be many surprises there that can effect the new code and the choices made.
  • Risk (surety) of new bugs.
  • Risk of breaking other code that uses your software.
  • New environment means new pipeline, install scripts, skills, documentation, etc.

A difficult choice

Yes the choice to rewrite the code is a difficult one. It should be. The consequences of this choice are big and should not be taken lightly. This does not mean that it must never be done. As described above many good reasons exist.

If you want to rewrite your code but want to stay on the same technology stack, you may want to reconsider that choice. Refactoring is probably a much better choice in that case.

Often a team will shout for a rewrite in the hope to escape the mess they themselves are accountable for. It is a good idea to verify this independently. If a rewrite is rewarded chances are high it will lead to the same situation of creeping technical dept. A waste of money, time and resources.

Experience learns that rewriting software with the same development team that produced the original version is seldom a good idea. As rewriting most likely requires a new set of skills it is ignorant to assume that the current development team is up to it. Before diving in it is a very good idea to research what the new technology stack will become and plan accordingly. Invest in schooling but also in the right resources.

If you have a large system to rewrite it is probably a good idea to hire a team of well-suited software engineers and provide them with the business knowledge from within the company. In the long run it is simply worth paying extra for experienced developers who have previously worked on projects with complex domains and large codebases. Such experienced and seasoned developers can help you through the process and ask smart questions. Mix them with your own employees so that they can absorb the way of working by being led by example.

Make sure you at least have a somewhat vaguely clear end-goal (vision). I say this with care as I do not advocate to go back to a waterfall based development, but when going for a rewrite it is necessary to have an idea of…

  • a product roadmap
  • of the technology stack you want to work with (conform marked standards)
  • the complete set of features
  • a working knowledge of your domain from a business standpoint
  • hopefully an idea of user journeys…

Knowing the above it will be much easier for engineers to make informed architectural decisions.

Know the value of a Minimal Viable Product and make sure to define this MVP with all stakeholders.

Be professional and try to leave ego’s behind.