Is high quality software worth the cost of its development?

Original author: Martin Fowler
  • Transfer

Often in the process of implementing projects, teams are faced with the question: what should be paid more attention to - the release of new features or improving the quality of the code? Typically, managers opt for features. Often, developers are unhappy with this state of affairs, believing that they do not have enough time to work on the architecture and quality of the code.

Betterridge Lawreads: "Any headline that ends with a question mark can be answered with the word no." 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 a formulation of the question suggests that there is a trade-off between cost and quality. And you must constantly maintain balance. In this article, I will prove that this compromise 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 developers, it does not require special knowledge to understand it. I would like this article to benefit everyone who is somehow connected with the development process, and especially to managers who form the product development vector.

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 the product and the costs 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 sacrifice some features. There are exceptions to this rule: sometimes a higher quality product is cheaper. And sometimes people can’t even objectively compare two products and choose a better one. For example, they do not notice the difference between screens that are made using completely different technologies. However, the statement “High quality costs more” is usually true.

Software quality is about a lot.


Speaking about software quality, you should start by defining quality criteria. What is quality software? From this moment on, things get a little complicated, because any computer system has many criteria by which its quality can be evaluated. You can evaluate UI and UX: how fast and simple can a user solve his problem? Reliability can be assessed: are there any bugs in the program that lead to incorrect and unstable behavior? Another criterion is architecture: how structured the source code of the program is, how simple and fast can the programmer find the piece of 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 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 to prolonged unavailability of the system. But users are not able to appreciate 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). Their most important difference is that users can evaluate the external quality, but they cannot understand how good (or bad) the internal architecture of the system is.

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


If users cannot evaluate 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 predicting flight delays. I manage one team, and Rebecca leads the second. The set of basic functions for the applications is approximately the same, the interface for both applications also turned out to be quite convenient and thought out, 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 messy set of classes and methods with obscure names and an even more obscure logic of how this code is interconnected. There is another difference: I sell my application for $ 6,

Since the source code of applications is inaccessible 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 internal quality, which does not matter to users?

If you develop this idea even further, you can come to the conclusion that investing in external quality is more profitable than in internal. 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 structure of the applications, not to mention the fact that the user can compare the architecture of the 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 internal quality are easier to expand


Why is it so important for programmers to have quality code? 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, he first needs to figure out how this feature fits into the existing application architecture. Then often you need 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 that these data structures mean what kind of relationships exist between them and what new data structures need to be added to implement features.

High quality code allows programmers to quickly navigate it. Reaching 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 this “technical debt” ( technical debt ), or in other words, the difference between the current state of the code and the ideal state in which it can be.

One of the main advantages provided by the high quality of the code is that the programmer can quickly understand how the system works and make the necessary changes. When the application is divided into modules, the programmer does not need to study all 500,000 lines of source code and he can quickly find the hundreds of lines he needs at the moment. When programmers give meaningful names to variables, functions, and classes, you can easily understand what each individual piece of code does without having 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 it is easy for the programmer to correlate the request for new functionality with how the system works. The technical debt also increases the time it takes to work with the code. The likelihood of making mistakes also increases. In case of bugs due to poor code quality, It will take extra time to localize the problem and fix it. And if the bug is not immediately noticed, then this will lead to problems in the production code and the fact that you will have to spend even more time fixing these problems in the future.

Each change in the code affects the future of the product. Often there is a situation where there is a simple and quick way to implement a new feature, but at the cost of breaking the current architecture (i.e. due to an increase in technical debt). If a programmer chooses this path, he releases his feature faster, but slows down the work of other developers who will have to support this code later. If everyone in the team does this, then even a well-designed application with good code will quickly grow into technical debts, and even a few changes will take several weeks.

Users want to get new features as quickly as possible.


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


Visualization of the influence of internal quality


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

The graph below schematically shows how you can imagine the ratio of functionality and the time it takes to develop it. Typically, a curve looks something like this:


This is how the development process looks when the code is not very high quality. At first, development is fast enough, but then more and more time is required to further expand the functionality. 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 discovered that something has broken, and this leads to additional time spent on testing and fixing 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 already written code. But this happens infrequently, because it requires a highly professional team with a good organization of work. But sometimes this still happens.


However, there is one trick. In the initial stages of development, ignoring code quality 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 represent pseudographics . There is no one true way to evaluate team performance. It is not easy to understand how bad code affects the final quality of the product (and if this correlation exists, how pronounced it is). By the way, this problem is relevant not only for the IT industry. How, for example, to evaluate the quality of work of a lawyer or doctor?

But back to the question, at what point is it worth starting to think about the quality of the code. Experienced developers believe that poor code quality begins to slow down within a few weeks after the start of the project. At an early stage of the project, the beauty of 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 new to the development process believe that bad code indicates 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 clearly, 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 very successful. The customer was delighted with the new system, both from the new features and from 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 have answered: “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, this is why experienced developers are called "architects." But in the process of creating software, there is always some uncertainty, uncharacteristic of other areas of activity, in which uncertainties are much less. Typical customers have a poor understanding of what they want from the program and begin to understand this only in the process of working on it. Most often, at that moment when they are shown the first versions 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 floors and change the layout at the lower, that half of the building is already 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 face of constant new challenges, the growth of their number and complexity, the teams constantly have to come up with 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 time of its solution, so I often hear the opinion that understanding what the architecture of a complex system should look like comes at least a year after the start of work. And even the world's most professional development team will not be able to make the system perfect.

A professional and organized team differs from a less organized one in that in the process of working on the system it creates less technical debt and also gets rid of the 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 identify problems faster and spend less time finding and fixing bugs. The members of such a team are constantly working to maintain high quality code and quickly get rid of bad code until it begins to interfere with moving forward. CI-systems also contribute to this, especially in a situation where many people are simultaneously working on different tasks. As a metaphor, you can bring in the kitchen after cooking. It’s impossible to cook something without staining 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 wash it. And the next time you want to cook something, it will be much more difficult for you to do this because first you have to wash the mountain of dishes.

DevOps Research and Assessment (DORA)


The trade-off between cost and quality is not the only one in the world of software development that seems simple at first glance, but in practice everything turns out to be somewhat more complicated. There is also widespread discussion of what is best to choose — fast development and release rates, or slower rates and rigorous testing. It is believed that the use of the second approach allows achieving higher stability of production systems. However, the DORA study proved that this is not so.

After collecting statistics over several years, the researchers identified which practices contribute to higher team performance. It turned out that the most effective teams update the production server many times a day, and the release of code from the moment of its writing to 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 pace can recover faster after a crash. Studies have also shown that in such teams processes are usually better aligned and they operate in a more organized manner.

Support for systems with a good architecture is cheaper


The most important points from what we talked about above:

  • Lack of attention to code quality leads to accumulation of technical debt
  • Technical debt slows system development
  • Even professional teams sometimes make bad decisions. But the application of modern practices and periodic "repayment" of technical debt allows you to keep it under control
  • Maintaining a high level of code quality minimizes 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 make it possible to maintain high quality code by limiting the time that is allocated for working on tasks. When answering management questions, why spend extra resources on the beauty of the code, developers usually answer that this is an indicator of high professionalism. But using only this argument implies that additional resources are spent on maintaining high quality, which could be used for other tasks. And this undermines the argument for professionalism itself. The truth is that due to poor-quality architecture and poor code, life becomes more difficult for everyone: it is more difficult for developers to work with it, and for customers it costs more. When discussing code quality with management, I urge that it be regarded solely as an economic indicator. If the program inside is done 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 true reason why the question from the title of the article simply does not make sense. Spending extra resources on architecture and good code, from an economic point of view, in the end, is more profitable. The trade-off between price and quality that we often encounter in everyday life cannot be directly applied to the internal quality of the software, but it can be applied to the external quality. For example, if it is a user interface. Since the correlation between value and intrinsic quality in this case is atypical and counterintuitive, it is often difficult to realize (and even more so explain to others). Nevertheless, it is important to realize this in order to make the development process as efficient as possible.



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


Also popular now: