Writing Maintainable Code — What is Software Complexity and How to Reduce It?
November 19, 2025
Hearing the word "complexity" likely triggers an intuitive response: code with low complexity should be easier to maintain, while code with high complexity becomes harder to work with. However, behind this intuition lies a more critical question: "What exactly is code complexity, and how do developers measure it?"
Consider this: when reading a piece of code, what makes you feel it's complex or simple? Why do you feel that way? How would developers measure complexity to confidently say "this code has high complexity" or "this code is simple"?
When tackling data structures and algorithms, developers typically use time complexity or space complexity to evaluate algorithm performance and make trade-offs. But when returning to our discussion on maintainability, what metrics should developers use to measure code complexity from a maintenance perspective?
Two Metrics for Measuring Code Complexity
There are many ways to measure code complexity. If simplifying to the most intuitive approach, two recommended metrics developers can examine while writing code are:
First is readability, second is changeability.
Readability
Readability refers to how long it takes someone new to the codebase who is unfamiliar with it to understand the code. If a newcomer needs a very long time to understand the code, that code has high complexity. Conversely, if a newcomer can quickly grasp unfamiliar code, the complexity is low.
Changeability
Changeability works similarly. When a future maintainer needs to modify a piece of code, how difficult or easy is it to change? If it's easy to change, the complexity is low. But if it's hard to modify, the code's complexity is too high.
With these two metrics to guide judgment, developers can further discuss how to write code that's easier to read and easier to modify.
Cyclomatic Complexity
Before diving into details, this unit covers broader perspectives on making code more readable and changeable. Later units will discuss specific principles in more detail that help write better, more readable, and more modifiable code.
First, let's discuss readability. In fact, the software industry has long used a metric called cyclomatic complexity to help measure how complex a piece of code is and whether it's readable for those maintaining it.
Cyclomatic complexity is based on graph data structures to measure code complexity. In a graph, there are different nodes. The more nodes in a graph, the higher its overall complexity becomes.
To make this more concrete rather than abstract, consider Tokyo's subway map as an example of a graph in everyday life.
In this graph, each station is a node. Each station connects to other stations, and some central stations connect to four or five different stations. Looking at a map with many nodes and stations, the diagram appears complex and overwhelming. In contrast, subway maps in cities with fewer stations feel simpler.
Nodes in Code
Applying this concept back to code: code also has different points that serve as nodes. The more nodes present, the more difficult and complex the code becomes to read.
Specifically, when measuring cyclomatic complexity in code, the nodes being counted are decision points. The most common are if/else conditional statements or for/while/do while loops.
Think back to code you've written or read. If a codebase has many conditional statements, it likely feels harder to understand. Each additional if, else if, or for/while loop adds one to the complexity score.
Methods to Reduce Cyclomatic Complexity
Now the question naturally arises: knowing we have a metric to measure cyclomatic complexity, what specific approaches can reduce complexity in code?
Using the function example from above, two recommended approaches developers can consider are:
Reduce conditional branches: Since conditional branches increase cyclomatic complexity, reduce them through various approaches.
Extract branches to helper functions: If effectively reducing branches isn't possible, extract branches into helper functions. This reduces complexity in the main function because complexity is distributed among helper functions.
(Note: The course video demonstrates two concrete refactoring examples that are difficult to convey in transcript format. Watching the video content for this section is recommended.)
Cognitive Complexity
While cyclomatic complexity is useful, developers often notice that using it alone doesn't always feel accurate in real code. Cyclomatic complexity overlooks cognitive aspects that human code maintainers experience when reading code. When considering cognitive factors, code with identical cyclomatic complexity can feel dramatically different in cognitive load—some code makes readers' heads spin while others feel manageable.
This is why the industry has shifted away from cyclomatic complexity toward cognitive complexity. Cognitive complexity incorporates the additional cognitive burden humans experience when reading code. Nested structures, for example, have higher cognitive complexity.
Readability Doesn't Equal Changeability
To lower the complexity impact on code maintainability, developers often discover that readable code doesn't necessarily mean changeable code.
Consider this example: three different components all use the color #FF5050. At first glance, this code seems readable, and most wouldn't find it hard to understand.
However, if these three components are scattered across three different locations in the codebase and you need to change the color, changing it becomes tedious—you'd need to update multiple places.
But if the color is extracted into a variable called primary (primary color), then if multiple pages need to change the primary color, developers only need to change the primary variable value once. Even if over 100 components use this color, only one change is needed, making it very easy to modify. In the first version, despite being readable, changing a color used by over 100 components would require updating over 100 locations, becoming tedious.
This example illustrates that readable code doesn't guarantee changeable code. In coming units, we'll emphasize principles that make code more changeable.
Summary
To write maintainable code and reduce complexity, two metrics are worth examining from a maintainability perspective:
- Code readability: How long does a newcomer need to understand the code?
- Code changeability: How much effort is needed for maintainers to modify the code?
With these fundamentals about code complexity covered, coming units will discuss practical methods to effectively reduce complexity and make codebases more maintainable.