[Translation] Is high quality software worth the cost of its development?

[Translation] Is high quality software worth the cost of its development?

Often, in the process of implementing projects, teams are faced with the question: what should be given more attention - the release of new features or the improvement of code quality? Usually managers make a choice in favor of features. Often, developers are unhappy with this state of affairs, believing that they do not have enough time to work on architecture and code quality.

Betteridge’s law says: “You can say no to any heading that ends with a question mark.” Those who know me personally know that I do not share this thought. But in this article I want to go even further and prove that posing the question from the title of this article simply does not make sense. Such an approach implies that there is a trade-off between cost and quality. And you need to constantly maintain a balance. In this article, I will prove that this trade-off is not applicable to the world of computer systems development and, in fact, creating high-quality software is ultimately cheaper.

Despite the fact that the main target audience of the article is the developers, for its understanding does not require special knowledge. I would like this article to benefit everyone who is somehow related to the development process, and especially to managers who form the vector of product development.

We are used to choosing between price and quality

As I wrote earlier, when developing software, you constantly have to make a choice between the quality of a product and the cost of its development. When you buy a new smartphone, you have a choice. Pay more money and get a faster processor, more memory and an improved screen, or pay less, but donate some features. There are exceptions to this rule: sometimes a higher quality product is cheaper. And sometimes people cannot even objectively compare two products and choose a better one. For example, do not notice the difference between the screens, which are made for completely different technologies. However, the statement: “High quality costs more” is usually fair.

Software quality is about a lot

Speaking of software quality, you should start by defining quality criteria. What is quality software? From this point on, everything becomes somewhat more complicated, because any computer system has many criteria by which its quality can be assessed. You can evaluate UI and UX: how quickly and simply can a user solve his problem? You can evaluate the reliability: is there any bugs in the program that lead to incorrect and unstable behavior? Another criterion is the architecture: how much is the source code of the program structured, how easy and fast can a programmer find the part of the code he needs at the moment?

The above list of quality criteria, of course, is not complete. But these criteria are enough to show one important thing. Some of the criteria by which the quality of a program is usually evaluated are not even visible to end users. Customers can give feedback and tell how well the software solves their business problems. Users may complain about the inconvenient interface. Or they will complain about bugs, especially if they lead to data loss or prolonged unavailability of the system. But users are not able to assess the architecture and quality of the code.

Therefore, I divide the quality criteria into two categories: external (for example, UI/UX or the presence of bugs) and internal (architecture). The most important difference is that users can appreciate the external quality, but they cannot understand how good or bad the internal system architecture is.

At first glance, internal quality does not matter to users (but only at first)

If users cannot assess the internal quality of the software, is this criterion important? Let's imagine a hypothetical situation that two development teams, independently of each other, decided to create an application for tracking and forecasting flight delays. I command one team and Rebecca directs the second. The set of basic functions of the applications is about the same, the interface of both applications also turned out to be quite convenient and thoughtful, there are no critical bugs in the applications. The only difference is that the source code of the application from Rebecca is clearly structured and organized, and the code created by my team is a random collection of classes and methods with obscure names and even more incomprehensible logic of how this code is interconnected. There is another difference: I sell my application for $ 6, and Rebecca sells almost the same application for $ 10.

Since the source code of applications is not available to users, and the quality of the code does not affect the user experience, why should users pay an extra $ 4? In other words, why overpay for an internal quality that doesn’t matter to users?

If you develop this idea even further, then you can come to the conclusion that investing in external quality is more profitable than in internal. By making a choice between two applications, the user can choose the one that is more expensive if he has a better and more convenient interface. But users do not see the internal device of applications, not to mention the fact that the user can compare the architecture of two applications. So why pay more for something that does not bring practical benefits? And why should developers spend time and resources on improving the internal quality of their programs?

Programs with high intrinsic quality are easier to expand

Why is it so important for programmers that the code be of high quality? Programmers spend most of their time reading and editing it. Even when developing a new system, work is almost always carried out in the context of already written code. When a programmer adds a new feature, first he needs to figure out how this feature fits into the existing application architecture. Then it is often necessary to make changes to the architecture so that a new feature can be implemented. Often you need to use data structures that are already in the system. Therefore, you need to understand what these data structures mean, what connections exist between them and what new data structures need to be added to implement the feature.

High quality code allows programmers to quickly navigate in it. To achieve a situation where the code becomes difficult to understand is actually very simple. Logical conditions can be intertwined, relationships between data structures can be complex and implicit. The names that Tony gave to variables and functions 6 months ago may have been clear to him, but also incomprehensible to the new developer, as well as the motives that prompted Tony to leave the company. Developers usually call it “technical debt” (technical debt), or in other words, the difference between the current state of the code and the ideal state it can be in.

One of the main advantages that high quality code provides is that the programmer can quickly understand how the system works and make the necessary edits. When an application is divided into modules, the programmer does not need to study all the 500,000 lines of source code and he can quickly find the hundreds of lines he needs at the moment. When programmers give clear names to variables, functions, and classes, it is easy to understand what each individual code fragment does without needing to delve deeply into the context. If the data structures in the program coincide with the terminology from the domain domain of the business, then the programmer can easily relate the request for a new functionality to how the system works.Tehdolg also increases the time required to work with the code. Also increases the likelihood of error In the case of bugs due to poor code quality, it will take additional time to localize the problem and fix it. And if the bug is not noticed right away, this will lead to problems in the production code and that you will have to spend even more time to fix these problems in the future.

Every change in code affects the future of the product. Often there is a situation when there is a simple and fast way to implement a new feature, but at the cost of breaking the current architecture (i.e., by increasing the technical debt). If the programmer chooses this path, he releases his feature faster, but slows down the work of other developers who will have to maintain this code later. If everyone in the team does this, then even a well-designed application with a good code will quickly accumulate technical debts, and even making a small edit will take several weeks.

Users want to get new features as quickly as possible

We come to an important point, namely: to answer the question, why is the internal quality of the software still important for users? High internal quality contributes to a more rapid release of new features, because they are easier, faster and cheaper to do. Our applications with Rebecca now look almost the same, but after a few months, Rebecca’s high quality code will allow her to release a new feature every week, and I’m stuck in place trying to cope with the technical debt and trying to launch at least one new feature. I can not compete with Rebecca in speed of development, and its application will quickly overtake my functionality. Ultimately, users will delete my application and will use the Rebecca application, despite the fact that it costs more.

Visualization of the influence of inner quality

The main advantage of the high internal quality of the program is to reduce the cost of future changes. But writing quality code takes more effort, and this increases the necessary resources in the short term.

The graph below shows schematically how you can imagine the relationship between functionality and the time it takes to develop it. Usually the curve looks like this:

This is what the development process looks like when the code is not very high quality. At first, development is proceeding fairly quickly, but then further expansion of the functional takes more and more time. At a certain point in time, in order to make even a small change, the programmer must first learn a lot of complex and confusing code. After the change is made, it is revealed that something has broken, and this leads to additional time spent on testing and correcting errors.

High internal quality contributes to the development efficiency at later stages. Some teams even manage to get the opposite effect, when each new feature is released faster than the previous one due to the fact that it is possible to reuse the code already written. But this happens infrequently, because it requires a highly professional team with good organization of work. But sometimes it does happen.

However, there is one trick. In the initial stages of development, ignoring the quality of the code is more effective than following high standards. But when does this period end?

To answer this question, you first need to clarify that the images show pseudographics .There is no one correct way to evaluate team performance. It is not easy to understand how bad code affects the final quality of a product (and if this correlation exists, then how expressed is it). By the way, this problem is relevant not only for the IT industry. How, for example, assess the quality of the work of a lawyer or doctor?

But back to the question, at what point should start to think about the quality of the code. Experienced developers believe that poor code quality starts to slow down a few weeks after the project starts. At an early stage of the project, the beauty of the architecture and code can be ignored.

Also from my own experience I can say that even small projects get a serious competitive advantage if they use modern and effective development practices in their work and think about the quality of the code.

Even the best teams sometimes write bad code

Those who are new to the development process think that bad code means that the team is not working well. But, as practice shows, even the most experienced teams sometimes make mistakes and write bad code.

To demonstrate this visually, I want to tell you about a conversation with one of our best team leads. At that moment, he had just finished working on a project that everyone considered to be very successful. The customer was delighted with the new system, moreover, from both the new features and the resources that were spent on its development. The team was also pleased with the completed project. The technical leader of the team was also very pleased with the result, but admitted that in fact the system architecture was not so successful. I asked him: "But how is it that you are one of our best architects?" He answered as any experienced architect would say: “We made good decisions, but only now we understand how to do it right.”

Many people compare the creation of complex systems with the design of skyscrapers. Apparently, therefore, experienced developers are called "architects". But in the process of creating software there is always some uncertainty, not typical for other areas of activity where uncertainties are much less. Typical customers poorly understand what they want from the program and begin to understand it only in the process of working on it. Most often, at the moment when they show the first version of the program. The elements from which programs are created (programming languages, libraries, platforms) change every few years. Drawing an analogy with the construction of a skyscraper, can you imagine a situation where the customer asks the architect to add another ten or so floors and change the layout of the lower floors, despite the fact that half of the building has already been built? The situation becomes even more complicated when it turns out that the technologies used for the production of concrete, its physical properties and characteristics are updated every 2 years.

In the conditions of constant new challenges, the growth of their number and complexity, teams constantly have to invent something new. Increasingly, it is necessary to solve problems that no one has ever solved before, and accordingly there is no well-known and proven solution for them. Usually, a clear understanding of the problem comes only at the moment of its solution, so I often hear the opinion that an understanding of how the architecture of a complex system should look like comes at least one year after it starts. And even the most professional development team in the world will not be able to make the system perfect.

A professional and organized team differs from a less organized one by the fact that in the process of working on a system it creates less technical debt and also simultaneously disposes of an existing one. This helps the project to develop rapidly and release new features as quickly as possible. Such a team invests in the creation of automated tests, which helps to quickly identify problems and spend less time searching and fixing bugs.Members of such a team are constantly working to maintain the high quality of the code and quickly get rid of bad code, until it starts to stop us from moving forward. CI-systems also contribute to this, especially in a situation where many people work on different tasks in parallel. As a metaphor, you can bring the cleaning in the kitchen after cooking. It is impossible to cook something without messing up the table, dishes and other kitchen utensils. If you do not clean them immediately, the dirt will dry out and then it will be much more difficult to clean it. And the next time you want to cook something, it will be much more difficult to do it because you will have to wash a lot of dishes first.

DevOps Research and Assessment (DORA)

The trade-off between cost and quality is not the only software development in the world that seems simple at first glance, but in practice everything turns out to be somewhat more complicated. Also widely discussed is whether it is better to choose - fast development and release rates or slower rates and rigorous testing. It is believed that the use of the second approach allows to achieve a higher stability of production systems. However, a study DORA proved that this is not the case.

Having collected statistics for several years, researchers have revealed which practices contribute to higher team efficiency. It turned out that the most effective teams update the production server many times a day, and the release of the code from the time of its writing to the release takes no more than an hour. Following this approach allows you to release changes in small parts, and the likelihood of serious damage is reduced. Teams that make releases less often, according to statistics, face a lot of serious problems. In addition, teams that are accustomed to a high tempo are able to recover faster after failures. Also, studies have shown that processes are usually better organized in such teams and they operate in a more organized way.

Support for systems with a good architecture is cheaper

The most important points from what we said above:

  • Insufficient attention to code quality leads to technical debt accumulation
  • Technical debt slows system development
  • Even professional teams sometimes make bad decisions. But the use of modern practices and periodic "repayment" of technical debt allows you to keep it under control
  • Maintaining a high quality bar allows you to minimize technical debt. This makes it possible to focus on new features and release them with less effort, faster and cheaper

Unfortunately, it is usually difficult for developers to explain this to management. I often hear complaints that the manual does not allow to maintain high quality code, limiting the time that is allocated to work on tasks. Responding to questions from management, why spend extra resources on the beauty of the code, developers usually respond that this is an indicator of high professionalism. But using only this argument implies that additional resources are used to maintain high quality, which could be used for other tasks. And this undermines the very argument about professionalism. The truth is that due to poor-quality architecture and bad code, life becomes harder for everyone: it is harder for developers to work with it, and it costs more to customers. When discussing the quality of the code with the management, I urge it to be considered solely as an economic indicator. If the program inside is made with high quality, it will be easier and cheaper to add new features to it. This means that investing in writing quality code ultimately reduces overall development costs.

This is the real reason why the question from the title of the article simply does not make sense.Spending extra resources on the architecture and good code, from an economic point of view, as a result, it turns out to be more profitable. The compromise between price and quality, which we often encounter in ordinary life, cannot be directly applied to the internal quality of software, but can be applied to external quality. For example, if we are talking about the user interface. Since the correlation between cost and intrinsic quality in this case is atypical and counterintuitive, it is often difficult to realize (and even more so to explain to others). But it is all the less important to realize this in order to make the development process as efficient as possible.

Martin Fowler has another article about technical debt. Small teaser:
The extra time spent on adding new features can be compared with interest on a bank loan. Cleaning a technical debt is like paying interest on a loan. This metaphor describes the essence well. But it can create a false sense that technical debt can be controlled quite easily. However, in reality it is much more complicated.

Source text: [Translation] Is high quality software worth the cost of its development?