How You Or Your Company Can Benefit From Code Refactoring
Code refactoring can make a big difference in keeping your company profitable. Read here how to renew old code. Refactoring is the revision of program code in order to eliminate existing architectural weaknesses. This article explains two possible ways to replace some or all of the old code with new code.
Refactoring of Code – Don’t Ignore Technical Debt.
There are some unpopular terms among project leaders and managers. One of them is undoubtedly “refactoring”. Are you part of the group responsible for a project, and one of the developers mentioned the need for refactoring?.
If you knew what refactoring was right away, you may internally flinch and go straight into a defensive stance. For everyone else to explain: the developer requires a lot of time and thus money to develop some things from scratch.
In the rarest cases, it is discussed but often reacted with incomprehension and a “Why, everything works!” countered. If you block out at this point, you could very well be in debt that will cost the company a lot of money.
Suppose refactoring has already been requested under your leadership as development manager, project manager or CTO. In that case, you are very likely responsible for it and have created or had a technical debt created.
Perhaps you can still remember the early days of the project? The enthusiasm was great, and new features were implemented quickly. After a few years, the opposite often occurs; It takes a long time to develop new features, and the motivation of the developers has dropped significantly.
In assessments of new features, sentences like “We don’t know how long it will take” are sometimes used. One reason for this phenomenon can be the fundamentally poor architecture. Subsequent changes cost a lot of money, and some can no longer be carried out at all.
Everything new or code refactoring?
There is no one-size-fits-all answer to this. However, dare to write completely new code if it is somehow representable. This will be much faster than refactoring the old code piece by piece.
This is mainly because they need for refactoring is justified in the destructive code, and, as with new features, it is difficult to add or replace new ones.
The sad truth is that existing code is rarely well documented, and there is often no well-maintained and structured technical information about what the program is supposed to do.
Don’t waste too much time analyzing your existing code to see what it is doing. Instead, please create a new list of requirements for what he must be able to do. You may also find that some logic is no longer needed because the conditions have changed over time, and old implementations have not been used after all.
A sore point in many projects is the lack of test coverage, for example, utilizing so-called unit tests, which automatically check parts of the program code for their function and correctness.
Even if most developers know that these tests are significant for quality assurance, they are often neglected and sometimes not written at all for decades. When a new program code is written, it is essential to ensure that this negligence is not repeated.
Test-driven development (TDD) should be requested without discussion to avoid this. By the way: If your developers find that automatic tests cannot check existing code, this is a reliable sign that the architecture is wrong.
Monoliths and Spaghetti Code
These are two terms that developers use. They each describe certain states of the product. First, let’s dive into the monolithic code.
The monoliths are not a bad thing by definition, but they often pose problems such as the difficulty of replacing parts or scaling up when the load increases. So it depends on the use of the software.
The conditions in a microcontroller are very different from those in an Internet application. It is a pearl of old programming wisdom to outsource parts to so-called libraries. This makes it easier for them to be tested and, due to their already separate nature, also easier to replace.
Monoliths are large programs that tend not to follow this division because everything has been integrated into a single project. The boundaries from one logic to another are not always clearly recognizable.
The so-called spaghetti code describes the interweaving of different program parts in a way that makes it challenging to recognize which fragments communicate with others in which form and which data are exchanged.
It can happen that information is passed through many shifts, and therefore, no clear responsibilities can be identified.
The monoliths and the spaghetti code turn the product into a black box. Something goes in, and something comes out. In between, there is an almost incomprehensible logic at work.
Code Refactoring: Methods in Practice
Have you decided on a refactoring of code? If the code is already reasonably modular, developers usually know how to replace these pieces. In this article, let’s assume the worst-case scenario: the monolith and the spaghetti code.
The replace bypass method.
First, it is necessary to isolate a program section so well that the incoming and outgoing information is clear. It is best not only to choose a small program section but also enough to isolate a technical function.
An understandable example is the creation of an invoice. Here, data such as the invoice items and addresses are to be transmitted to a process, and a PDF is returned as a result. A developer can develop this new function separately and treat it as a library, naturally test-driven by unit tests.
In the so-called legacy code (the old code), the isolated section is no longer called, and the new library is used instead. Since, in practice, it is not necessarily the case that the necessary data is suitable for the new library, it may be required to prepare it with additional code.
An example of this is creating objects from existing lists with simple data types, which corresponds to object-oriented programming. The legacy code and the library agree on a standardized format with so-called interfaces.
Do not necessarily remove the legacy code at this point if you are not sure about the technical nature or the stability of the new code. For example, a switch can be installed that uses environment variables or program parameters to ensure that the legacy code is used again quickly.
This enables you to quickly bring about the old behaviour in the delivered product without dismantling everything and redelivering it. If the new solution has proven itself after a while, the legacy section should be removed.
The new frame method
Unfortunately, the replace bypass method does not solve the more fundamental problem of the poor overall architecture. Even if parts have been replaced, the basic structure is retained.
If you first create a new framework, a basic framework in which the business logic is integrated with the designated places. This would also be the recommended course of action when developing a completely new product.
The catch here is that this framework initially offers no business logic, i.e. does nothing recognizable. Still, a clean structure is a catalyst for better code. Conversely, a lousy framework is also a promoter of destructive codes. There is the effect that horrible code often allows more lousy code.
How quickly does the old business logic get into the new framework? The previous product may allow the integration of simple interfaces that the new framework can call, even if only retrospectively. The old product can be used in the background until replaced by a new program code.
The methods mentioned can also be combined by first replacing parts of the old product but then quickly integrating them into a new framework. The framework of the new product can thus be designed in parallel.
There are more options than those mentioned above. When choosing the process, the nature of the existing legacy product is fundamental.
When to refactor?
If the product is to be expanded further, then immediately! The debt does not get less, but more with every change. It is also not advisable to refactor new features simultaneously to develop. Take a little “feature break”. Otherwise, the developers could have duplicate work.
Refactoring belongs in every sprint. It must be planned that the code is only “ready” when tested and documented, and a review and evaluation have taken place. If the topic for a feature is still up-to-date in mind, revising it is the quickest. Before much discussion, the developer should do this mini-refactoring before finishing.
That is part of the craft, resulting in his digital legacy. It is unwise to veto this on project managers or CTOs just because the word “refactoring” has been used. The discussions on this topic can take longer than the activity itself.
Avoid technical debt
Software architects are considered to be very experienced programmers. This group deals with program code for the fulfilment of features and has a technical understanding of essential quality characteristics. These include:
- Changeability,
- Interchangeability,
- Reliability,
- Stability and
- Safety.
Modifiability, in particular, has a massive impact on the cost of new features. A software architect knows some architectural rules, which means qualitative software is promoted.
Yes, it is possible to make sure that everything is developed correctly in advance. And like in house building, at the beginning of the project, you should give an architect time to design the proper framework. This can take weeks or months, and the investment is expensive.
However, minuscule compared to what a company would have to invest in a row to offset the technical debt. It is often said that programming has to be done quickly and that individual parts can be reprogrammed later.
However, the latter seldom happens because of the chronic lack of time development. This shows that it is the responsibility of the management to promote constant refactoring and train employees in their understanding of architecture and quality.
If the project is very advanced technology or has been in development for many years, don’t mistake having a junior developer create a new version in parallel. That has to be mentioned, as this process can be observed repeatedly.
Software architects typically have more than a decade of experience. A junior can’t keep up with that and will likely create another product with technical debt. It looks better when the last team develops the new creation because it hopefully learns from mistakes.
However, it is also highly recommended that the group be led by an architect who can use his experience to avoid new or undetected problems. An architect who has not yet been involved in the project can bring new perspectives here. (BW)