What’s Wrong with Software Complexity?
This article is part of our series on Technical Debt. See other articles in the series:
In this article you will learn:
What is Software Complexity (Code Complexity) and What’s Bad About it?
Software is an intangible product, which is notoriously difficult to measure (see our in-depth article on software metrics). However, one aspect of software which can be easily quantified is its complexity.
Complexity reflects the number of entities that comprise the software, and the number of interactions between them.
The higher the complexity, the more difficult it is to read the code and maintain it, and the higher the likelihood of faults and defects.
How Important is it to Measure Code Complexity?
Measuring code complexity can help you address the problem while it’s still small:
- By measuring complexity you gain awareness of the magnitude of the problem – how much technical debt is piling up in the form of overly complex code
- Measuring complexity on an ongoing basis can capture trends or spikes in complexity – for example, a new developer on the team might be generating overly complex code
- Collecting data on complexity can help teams communicate with members and management, and decide to allocate more time to enable developers to simplify and refactor their code.
Code Complexity Metrics
The following metrics can be used to measure complexity:
|Cyclomatic complexity||Measures the degree of control flow in a program. For example, operations like IF, DO, SELECT represent conditional logic which makes the program more difficult to understand. The more operations like these exist in the code, and the more logical branches they contain, the higher is cyclomatic complexity.|
|Halstead Metrics||Measures how much distinct information exists in the source code, including the number of variables and how often they are used in source code, methods and functions. The assumption is that the more individual elements within the code, and the more often they are used, the more complex the program.|
|Maintainability Index||Computes a score of how maintainable a program is, based on a combination of cyclomatic complexity, halstead volume, normalized by the number of lines of source code and number of lines of comments.|
|Object Oriented Design Metrics||Quantitative metrics for object oriented (OO) design focus on class and design attributes. They allow designers to assess software early in the development process and understand how to reduce complexity and improve maintainability. See M. Sarker’s paper for a detailed review of OO metrics.|
|Data Complexity (Chapin Metric)||A metric that assesses the complexity of software code by checking how different software metrics are affected by automated obfuscation of the code.|
Long Term Benefits of Software Complexity Analysis
Measuring software complexity on an ongoing basis helps project teams and technology management detect problems early in the development cycle, and identify areas of source code where complexity is high or increasing. Catching complexity problems early in the game is important, because as more and more code is written, tested, and pushed to production, refactoring becomes an order of magnitude more difficult.
The main benefits of measuring software complexity include:
Improving Code Quality
It is widely recognized that complex code, in most cases, is not quality code. Measuring and monitoring code for complexity is a warning signal that quality might be an issue. However, complexity metrics are not enough. Programmers need to be given time, training, and assistance – commonly in the form of mentoring or pair programming – to improve the quality of their code.
Reducing Software Maintenance Costs
There is a clear and proven inverse relationship between complexity and the ease of maintaining a code base. Reducing complexity will, in almost all cases, reduce the work required to fix bugs or modify parts of the code.
Improving Developer Productivity
Developer productivity is typically measured in terms of velocity – how many new features, bug fixes or tests a developer is able to complete in a development iteration. Developers almost always work on improving and extending existing code, and the less complex the code, the faster and easier development will be.
Improving Software Robustness
Because simpler code is easier to read, understand and test, it is also much more likely to be robust to changes, and less likely to be unexpectedly affected by error conditions.
Unmanaged Code Complexity = Technical Debt
According to many experts, complexity is a type of technical debt. Developers might be turning out overly complex code because:
- They are under pressure to deliver something that works – it is typically easier to churn out complex, spaghetti code compared to clean, elegant code
- They haven’t been trained in the art of quality coding
- They aren’t aware of the importance of code quality, and there is no organizational process to monitor complex code and encourage good coding
When developers write complex code, that code represents technical debt that will need to be cleaned up in the future, to ensure the code is readable, reusable and maintainable.
Using Analytics to Eliminate the Risk of Software Complexity
All software projects contain a certain degree of complexity, and in practice, it is impossible to weed out or refactor all overly complex code. The trick is to identify which of the complex code has a higher impact on your users, and focus your efforts there.
A new category of tools, called Software Quality Intelligence, can help identify areas of your product which represent a quality risk. Quality intelligence does this by analyzing which parts of the codebase were recently changed, are not sufficiently tested, and are commonly accessed by users in production. By identifying code at risk, you can focus your refactoring efforts and simplify complex code where it matters most.
Also check out our white paper, Eliminate the Risk of Your Team’s Technical Debt Using Analytics, to learn how to use analytics to keep complexity and technical debt at a level that does not affect performance and long-term goals.