Free sample lesson ยท A Philosophy of Software Design
Complexity Fundamentals
Why do software projects that start simple become nightmares to maintain?
Lesson 1 of the Wondering course A Philosophy of Software Design
Why Simple Projects Turn Painful
Most software starts small and easy to follow. A few files, a clear purpose, quick changes.
Then it grows. Each new feature adds more to understand, and changes start taking longer.

Notice that the developer is the same on both sides; only the amount of structure to understand has grown.
The greatest limitation in writing software is our ability to understand the systems we are creating.
That limit is why complexity decides whether a project succeeds or fails over the long term.
What Complexity Actually Is
Complexity is anything related to the structure of a software system that makes it hard to understand and modify.
- Complexity: Anything in a system's structure that makes work harder.
- Hard to understand: You struggle to follow what the code does.
- Hard to modify: You struggle to change it safely.
Notice the two tests. Can you understand the code? Can you change it safely?
If any part of the structure makes either one harder, that is complexity.
Size alone is not the test. The question is whether the way code is organized gets in the way of understanding and change.
Complexity Creeps In
Complexity rarely arrives all at once. It accumulates incrementally.
One quick workaround. One extra special case. One shortcut to hit a deadline. Each seems harmless alone.
- Clean start: The system is small and easy to follow.
- Small decision: A workaround or shortcut seems harmless alone.
- More decisions: Special cases and shortcuts keep piling up.
- Compounding: Together they make the system hard to understand and modify.
But small decisions compound over time. Together they turn a clean system into an unmanageable one.
No single bad change explains the mess. That is why every small choice deserves attention.
The Real Goal of Good Design
If complexity is the problem, what does success look like?
The ultimate goal is to minimize the amount of code a developer needs to understand to make changes.
Picture fixing a bug. In a healthy system, you read one small area and make the change with confidence.
In a complex one, you must trace through many files before you dare touch anything.
Two Ways to Fight Complexity
There are two general approaches to fighting complexity.
Make code simpler and more obvious. Remove what is not needed so readers grasp it quickly.
Encapsulate complexity through modular design. Hide the hard parts inside modules, so others can use them without studying their insides.
- Simpler code
- Modular design
Strong designs use both. Simplify what you can, then contain what remains.
How Encapsulation Helps
Some complexity cannot be removed. A system may truly need tricky logic.
Modular design puts that logic inside a module, a self-contained part of the system.

The tangled logic stays sealed inside the box, so the developer outside only needs to understand the simple surface.
Other developers work with the module from the outside. They do not need to understand its inner details.
The complexity still exists, but fewer people must think about it at once. That shrinks the code each developer needs to understand.
Spotting Complexity in Your Work
You can now spot complexity in everyday code.
Ask two questions about each change: Is this easy to understand? Is it easy to modify?
If not, first try to make it simpler and more obvious. If the hard part must stay, wrap it in a module.
Small decisions compound, so treat each one as part of the long-term design.
Check yourself
In software design, complexity is anything related to a system's structure that makes it hard to _____
- understand and modify
- compile and execute quickly
Answer: understand and modify
Complexity is about structure that makes a system hard to understand and modify. Slow execution is a performance concern, not the definition of complexity.
One way to fight complexity is to make code _____ and more obvious. The other is to hide complexity behind clean boundaries, called _____ design.
Answer: One way to fight complexity is to make code simpler and more obvious. The other is to hide complexity behind clean boundaries, called modular design.
The two strategies are eliminating complexity by making code simpler and more obvious, and encapsulating complexity through modular design so developers don't need to deal with it all at once.
Which situation best illustrates software complexity?
- A small feature change requires reading and editing many tangled files
- The program runs slowly on an older laptop
- Users dislike the color scheme of the app
- A developer mistyped a variable name once
Answer: A small feature change requires reading and editing many tangled files
Complexity is structural: anything that makes a system hard to understand and modify. A small change needing edits across many confusing files fits exactly. Slow hardware, bugs from typos, or user preferences are not about structure hindering understanding.
Keep going
This is lesson 1 of 25 in A Philosophy of Software Design. Next up:
- Complexity Symptoms
- Strategic Programming
- Deep Modules
- General-Purpose Modules
- Different Abstractions
Wondering turns any topic into short lessons you can read, watch, or listen to, with practice questions and an AI tutor.