📜 ⬆️ ⬇️

Old code: why is it so

Most of the developers sooner or later face the need to change something in the code, which for many years. By that time, a lot of programmers had worked on this code, replacing each other, and each of them changed or added new pieces.

Typically, such a code can be found inside the flagship solutions of product companies engaged in the release of products for a long time on the market.

At once I will say that the problem of the old code cannot fit into one article, so I have broken the pain into several parts. Today we will talk about what distinguishes the “old code”. In the next article, based on the experience of writing code, project management and communication with the business, I will write a few thoughts on how to deal with it.

Performance and Economics


Usually the old code is 100% workable. Well, or to be honest, 95%. Pain begins when changes need to be made to the system, especially when changes lead to the appearance of floating bugs, which usually take up most of the time to fight.
')
Classics advise to periodically refactor such systems before it is too late. However, it includes economic factors, which are described below.

Modifying the old code is not only technically easy. On the old production code solutions are built (very often - flagship), which can earn millions of dollars for a business. Therefore, when working with such a code, not so much technical as economic constraints are imposed on the command.

Any changes affect a large number of users and may adversely affect the stability of the product. If the product is the flagship and brings a lot of money to the company, the breakdown of stability can cost the company a pretty penny. In this case, the anecdote about the sysadmin’s son more accurately describes the situation: “then, for God's sake, do not touch anything, do not change anything!”.

Obviously, in such a conservative atmosphere, changes are at least highly undesirable, and most likely impossible without careful coordination with many stakeholders. And, if the changes are dictated by business needs (usually, these are new features or attempts to improve the current ones), then it is much easier to justify them than “refactoring” or, especially, “rewriting everything anew.”

How to justify refactoring to business is the topic of a separate article. In short, three factors must come together for this:

As you can see, of the three factors, two and a half depends on the needs of the business to change and incur additional risks. Unfortunately, these factors depend little on how much pain working with legacy code delivers to developers / administrators.

Knowledge guru


By the way, very often making changes even to the ancient and terrible Legacy code can occur quickly and more or less efficiently.

This usually happens when an expert guru works with the code, who keeps in mind all the intricacies of logic and can very quickly add another lump of clay to the current implementation.

In this case, everything becomes much more complicated: on the one hand, business requirements are fulfilled on time and “completely to myself”. On the other hand, even the most experienced and advanced programmer cannot keep in mind all the functions of a huge system and (the farther away the more often) when making changes, something imperceptibly falls off in a completely different end of the code. Especially often this is manifested if several commands use the same code (each in its own way).

Needless to say, the attempts of someone else to work with this code lead to enormous effort. The guru author keeps knowledge of the in-memory code and remembers (if you're lucky) the history of clogging one or another crutch, while the new programmer has to wade through the intricacies of crutches overgrown with age-old moss and understand the device from scratch.

Well, we can not forget about the bus-factor. If the "same" programmer leaves the company, the code slowly begins to turn into a pumpkin. By the way, the time of the work of such a code after the departure of the author is directly proportional to his skill and can reach several years. But, alas, “working” does not mean “developing” and making changes to such a code is either simply impossible or destroys the entire system.

Confusing logic


Everything is simple - over the years of using the code, so many changes were made to it by different people with varying degrees of thoroughness that no one remembers the original logic, and only the guru from the previous paragraph knows (how and that is not completely). All this is aggravated by the lack of documentation and unit tests (which ideally) can also be considered as documentation.

Irrelevant documentation and unit tests


This item (like all previous ones) is not a general rule. I have seen components that have been living for a dozen years, completely covered with tests and with excellent documentation. However, such components are more similar to the participants of the beauty contest of Brazilian grandmothers - they are few and, other things being equal, they are quite rare, and it’s completely impossible to say how old they are.

Why the code is not documented and unit tests are not written, it is a separate big story. But the main reason, of course, is the lack of time. Especially conscious teams even sometimes write documentation at the stage of writing software (and particularly conscious PMs even plan for this time). However, in our changing world and the flow of demands from the business, supporting such documentation becomes a daunting task that requires a considerable amount of valuable developer time. Imagine that for every change, in addition to the code, you need to write or correct a couple of paragraphs of text!

As a result, sooner or later, the documentation freezes at the level of "this was last year, but now everything has changed." Alas, the paradox of documentation is that, where it is really needed - in the most difficult, confusing and even seemingly illogical places, its writing and support takes an unjustified amount of time and effort and is usually postponed.

Approximately the same thing happens with unit tests. I admit honestly: in my memory, of all attempts to write and maintain unit tests with more or less complete coverage, only the honest TDD scheme came together, when the infrastructure for the tests and the tests themselves were written before the main code was written. Attempts to write tests after writing the system were usually failing or limited to only minimal coverage (usually the code that is easiest to test).

On the other hand, although tests require the same support as documentation, projects covered with tests at the proper level are found in nature much more often. Probably, test writing is perceived by programmers as writing code, but “writing documentation is for technical writers.”

What's next?


I understand that this post turned out to be more overview than useful. To correct this omission, in the next "releases" I will share thoughts on how to avoid premature aging of the code and what to do so that even in old age the code remains clean, beautiful and maintained and looks like Jane Fonda .

Continuing the theme: Maintenance code. How to sell refactoring to business

Source: https://habr.com/ru/post/266803/


All Articles