📜 ⬆️ ⬇️

Technical Debt Management

Ekaterina Sazonova, a freelance translator and a student at Netologi , has translated the article by Carl Tashian on how to deal with product and project managers specifically for the blog.

image

A lot of books have been written about the problems of software development, its evaluation, cost control, testing. I want to share with you proven practitioners who have helped me, as a technical manager, keep technical debt under control in a growing project.
')

Maintain flexibility in the right places.


Design software as you would design a building. Something in the construction is moving slowly, something - quickly. Some components, such as furniture or painting walls, are not directly related to the building itself. It is very difficult to change the angle at which the walls are located to each other. Need to prioritize.

Understanding what can be flexible in a program, and what is not, refers not only to current requirements, but also to future ones. That is why it is so difficult to create software. You are not just supplying your technology product, you are trying to predict the future. And the future is covered with darkness, there is always the risk of premature optimization. You have to make a choice: which component is fundamental, and which component can be easily changed.

The word software (literally "soft product", appeared in contrast to the "solid product" - hardware) distorts the essence of the concept, because it implies flexibility in everything. Flexibility in everything is the ideal to strive for. However, the truth is that a more stringent system with very closely related components is much easier to build. For example, it can be argued that in a monolithic application the elements are interconnected more strongly than in the set of microservices. The obvious advantage of a monolithic application is its simplicity. Do you want to write at least a line of code for an application based on microservices? Study first the giant list of requirements for data exchange, coordination and availability of system elements.

This does not mean that microservices solve the problem of communication between modules. They connect modules with a network that allows you to build clear, delineated domain boundaries, but the connection itself is inevitable.

Flexibility is expensive. I cannot even count how many times I created something with an idea of ​​how the requirements will change in the future, and then I discovered that it is necessary to change the “fixed” parts, and the flexible ones do not have to be flexible. At first, I thought I was just unlucky, but now I realize that I was simply wrong when planning.

The software, unlike the building, becomes outdated differently. If the requirements do not change, the foundation will not move and will not begin to collapse, as it does with a building. Software does not wear out. However, its foundation is affected by new requirements. Startups are very difficult to make the right choice. Try to solve this problem with the help of cloud services, laying the possibility of scaling from the very beginning. Optimizing cost and speed management as you grow will require a lot of fundamental work. Even with modern cloud solutions, microservice management mechanisms and so on.

Speed ​​refactoring


Refactoring is one of the best ways to increase overall performance. This has already been said a lot. In any sufficiently large code base, there is something to change. The main thing is to refactor in the right place, where simplification and flexibility will be needed in the future. So that it does not resemble a guessing game, it will be right to refactor before introducing new functions.

Before you write the code, accept the fact that it will have to throw away


A simple way to reduce technical debt is to understand that any code is only a temporary experiment. For example, you decided to create a separate branch of code and quickly sketch out a prototype that you can implement. Even if everything will be fine with this feature, you will have to re-write the code properly, and throw out the old one. Such prototyping is specific and carries many risks: some people in your team will have to lower their standards. However, this method will save you time.

Work with tests and analyze code


Testing is a way of life, a sacred practice. Even in small projects, testing saves more time than the process takes. Sometimes it can be seen immediately, sometimes later.

The company should be taken to carry out code review. It doesn't matter how many tests you write, how well you can refactor. Other people will notice the moments you missed. Errors. Bugs. Typos. Yes, whatever. In many companies, three pairs of eyes check every line of code — I think this could be a general rule.

The frequency of testing and conducting a code review should be commensurate with the damage caused to the project in case of failure. Source code requires more thorough verification than interface code. Any software related to the insulin pump should be tested more seriously than any mobile application. Can you imagine a team working on an insulin pump with the slogan "Do it fast and crash"? (Facebook development mantra and Mark Zuckerberg's motto “Make fast and break things”).

Kill badly working features


A friend of mine, engineer Noah Thorpe, once told me: "We pay for every line of code every day." The less code, the less you pay. When I work on a project, it is important to me how each feature works. I regularly assemble a team to decide which features to improve and which ones to remove. This means, from time to time, to admit to yourself that the feature that you like simply does not work.

The ideal situation is this: you understand that the feature will work incorrectly before you write code. On the first line of defense are paper prototypes and user tests. However, you are always under pressure. You can always hear the hubbub of people using the product and asking to add such terrible features that should never be realized. Or such features that could be added, but later. This is where product management and technical design meet: even if creating a new feature is a common thing, you still have to pay for it.

Minimize dependencies


You have to pay for dependencies too. Dependencies are internal and external. Internal - these are libraries and frameworks that your software depends on. External are services with which your software is connected. You are doubly dependent on services, because libraries are usually associated with them.
By adding a library to your project, you pay for the entire library and your use of it. So, you need to justify the need for each library, each plugin. Even the smallest. They are added quickly. If you have a balanced approach, you will be surprised how quickly you will progress.

It is easier to apply all these methods if they become general principles of work in your company and a favorable environment is created for their use. Maintain a high level of code review with requests for code inclusion (pull request). Continue to constantly test, maintaining a system of continuous integration (Continuous Integration). Monthly discuss the main features. Keep handy paper books that talk about the right approaches, for example, “Refactoring: improving the structure of an existing code” (“Refactoring: improving the design of the existing code”). And do not forget to read them!

It is important to clearly understand what you are building. Will it be a secret refuge by the sea, typical housing or a glass art museum? The answer to this question should be the same for the whole team. That is why technical debt management is not only the work of a technical manager or developer. This is a common work. After all, it affects every step of the product development process, starting with planning.

From the Editor


Courses "Netology" on the topic:

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


All Articles