BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage Articles Understandability: The Most Important Metric You’re Not Tracking

Understandability: The Most Important Metric You’re Not Tracking

Leia em Português

This item in japanese

Key Takeaways

  • Change is the only constant in life. Nowhere is this more apparent than in software engineering, where a developer’s daily job is to modify, adapt, tweak, or even remake the systems they are responsible for. 
  • As applications grow and teams scale, it becomes more challenging to maintain a clear understanding of the software itself. Complexity hurts engineers’ ability to understand and effectively change the software as needed. 
  • Understandability is the concept that a system should be presented so that an engineer can easily comprehend it. The more understandable a system is, the easier it will be for engineers to change it in a predictable and safe manner.
  • A system is understandable if it meets the following criteria: complete, concise, clear, and organized.
  • Understandability and observability are complementary, but the latter focuses more on two things: the ability to alert when the system misbehaves and help to identify the causes so that normal service can be restored; and the ability to help identify performance bottlenecks so that additional resources can be allocated or that the relevant teams be informed.
     

2,500 years ago Heraclitus said that “change is the only constant in life.” Nowhere is this more apparent than in software engineering, where a developer’s daily job is to modify, adapt, tweak, or even remake the systems they are responsible for. Another such aspect that makes software engineering relatively unique among human disciplines is the vast freedom we have to mold our works, within the man-made boundaries defined by the mechanics of computer science.

Our ability to effectively exercise that great power often falls short on a very surprising limitation —our ability to know our own creations. As applications grow and teams scale, it becomes even harder to maintain a clear understanding of the software itself, causing projects to crumble like the biblical Tower of Babel.

Case in point

Most commercial software engineering tasks out there do not start out with a clean slate. There is an existing application, written using a certain computer language(s), relying on a set of frameworks and libraries, and running on top of some operating system(s).

We take it upon ourselves (or our teams) to change that existing application so that it meets some requirement(s), such as developing a new feature, fixing an existing bug, etc. Simultaneously we are required to continue meeting all the existing (un)documented requirements, and maintain the existing behavior as much as possible.

And, as every junior software engineer finds out on their first day on the job, writing a piece of code to solve a simple computer science problem (or copying the answer from StackOverflow) is nowhere near the level of complexity of solving that same problem within a large and intricate system.

What is Understandability?

Borrowing from the financial industry, let’s define Understandability: “Understandability is the concept that a system should be presented so that an engineer can easily comprehend it.” The more understandable a system is, the easier it will be for engineers to change it in a predictable and safe manner.

Drawing further on that analogy, we can say that a system is understandable if it meets the following criteria:

  • Complete. The system must be presented using a predefined set of sources (source code, documentation, etc.) to cover all key information. No critical pieces of information may be left to the engineer’s imagination.
  • Concise. The system source code should not bury the user with an excessive amount of detail. This is where separation of concerns and abstraction come into play, allowing the engineer to focus on the task at hand.
  • Clear. Use a presentation methodology that is easy for the reader to scan. This is where consistency, coding conventions, source-code formatting, code comments, and syntax highlighting make a huge difference.
  • Organized. The engineer should be able to easily locate cross-referenced information within the system. This is where modularity, software documentation, source-code navigation controls, and source code management tools allow engineers to find their way around the system.

Runtime Understandability

With the rise of Software as a Service (SaaS) and other new software delivery paradigms, many organizations are practicing total ownership of software, empowering engineers to take responsibility for the application throughout its lifecycle.

In such organizations, Understandability takes on an even more powerful form, determining how well engineers can understand how the software operates and how it is being utilized by the application’s customers.

And so, highly valuable information such as usage patterns, real-world inputs and outputs, and actual performance and availability statistics can become accessible to teams determined to have them.

Observability is not Understandability

Reading this you might be thinking, that’s exactly what observability and monitoring tools are for. Unfortunately, that’s not the case. Those tools are there to support more traditional IT problems, focusing on:

  1. Alerting when the system misbehaves and helping to identify the root so that normal service can be restored.
  2. Identifying performance bottlenecks so that additional resources can be allocated or that the relevant teams be informed.
  3. Keeping detailed event logs for operations, security, and support purposes.

Those are all great use-cases IT has been dealing with since time immemorial, and as the ROI for them is quite clear, a large number of vendors are offering great tools to solve those problems. However, those are not the use cases software engineering teams are tasked with, and those tools were never meant to help them.

What all of those IT use cases have in common is that someone, with a basic working knowledge of the system, needs to know exactly how the system behaved in a specific instance so that they can respond to it appropriately. This means we collect data about a predefined set of events, which tends to be about how the system is interacting with the world around it.

Software engineering teams, on the other hand, have an in-depth knowledge of the inner workings of the system and are looking to understand more about how it works. The data they need to collect changes on a daily (if not hourly) basis, based on the specific change they are making to the system.

Winning over complexity

As software scales and mutates, it becomes ever more complex. A big part of that complexity is inherent, due to the simple fact that the number of business requirements is ever-growing. The rest of that complexity is unwanted, caused by the way the application has been repurposed over time as well as poor design choices and is commonly referred to as tech debt.

Regardless of its source, complexity hurts engineers’ ability to understand and effectively change the software as needed. This problem is usually aggravated by the knowledge loss caused by personnel turnover.

Of course, in the software industry, it is common knowledge that software complexity has to be minimized. The more complex the software, the more expensive it will be to develop new features and the overall quality of the system will be lower. Much has been written on how to build application software that keeps complexity to a minimum and allows systems and teams to scale better.

Understandability in new software

If you are developing new software, you will likely neglect Understandability in favor of one of its proxies: complexity. By focusing on avoiding and reducing complexity you will naturally maintain understandability. Lucky for you, complexity in software is at the focus of countless software development tools and techniques.

First and foremost, start with a high-quality workforce. Talented engineers draw on their experience to express complex business problems in simple and elegant ways in both the software’s source code and architecture, creating an easier to understand software.

Next, try to make the system as small as possible, since smaller systems by nature are less complex and easier to understand. Systems can be reduced from the “top” by focusing on the business requirements that truly matter, while leaving out, at least temporarily, requirements that are not mandatory. Systems can often be reduced from the “bottom” as well, by using higher-level abstractions, such as new programming languages, advanced frameworks, and modern databases.

Last but not least, make sure to have the scaffolding in place to deal with complexity when it arises. Write automated tests in the form of both unit-tests and system-tests to ensure that your engineering team can safely refactor that complexity away. Put in high-quality observability tools to help you gain a high-level understanding of the system. Automate your integration and deployment pipelines to enable you to improve and iterate fast.

Understandability in existing software

When it comes to existing software, on the other hand, we tend to accept our engineering team’s failure to understand the code as a god-wrought catastrophe. Charging at complexity head-on is no longer a viable approach to improving Understandability.

More often than not, you are faced with a legacy system that was written using lower-level instruments than what is currently available, by people who have long ago left and none of the scaffolding is there. Complaining about the technical debt you have to cope with and the “unreadable code” your engineers cannot understand is not going to get you very far. Nor will dreaming about long-term refactorings and migrations which will rarely ever come to pass.

That’s where production debugging platforms shine. By allowing your engineers the in-depth view of the code in motion they are striving for, they can begin to understand it. And by following the cookie crumbs across environments and use cases, they can unravel that complexity step-by-step.

Parting words

We now have a better perspective on the importance of Understandability in software development. On the one hand, we always knew that keeping code easy to read and maintain was important and that much of software engineering was focused on that feat. And yet, we now have a greater appreciation for how much of a difference it can make in allowing software to grow and evolve over time.

On the other hand, we have also challenged the assumption that Understandability can always be improved by tackling complexity and designing and writing better, simpler software. More often than not, we find ourselves boarding the train midway through, with little or no control over how it got there. And so, we must start tracking and managing Understandability as its own key metric, maximizing engineering velocity and quality, even under less than optimal conditions.

About the Author

Liran Haimovitch is the Co-Founder and CTO of Rookout. He’s an advocate of modern software methodologies like agile, lean, and devops. Liran’s passion is to understand how software actually works. When he’s not thinking of code, he’s usually diving or hiking.

Rate this Article

Adoption
Style

BT