> For me, the fundamental goal of software design is to make it easy to understand and modify the system. I use the term "complexity" to refer to things that make it hard to understand and modify a system.
This explains everything that's wrong with modern software.
When you design a Formula 1 race car engine, the purpose of engine design is not to "make the engine easier to modify". It's to win races. And that depends on the race - a funny car engine, a formula 1 engine, a LeMans engine, Nascar engine, etc, are all different because the races are different.
Another example: when you design a building, the goal isn't to make it easier to understand the building. The goal is to meet the requirements of the building, its uses, requirements, environment, etc. Sometimes a better building is just more complicated, and making the architect or builders' jobs easier, while nice, isn't the goal.
Some things aren't supposed to be easy to understand, because ease of understanding is not the goal of the thing. Focus on the real goal of the thing, and achieving that; don't get distracted by ancillary goals.
Software is unusual in that it's never finished. This makes ease of modification a critical quality of software in a way that it isn't for Formula 1 race car engines or most buildings.
Ease of modification was one of the top priorities in the design of the Model T Ford, because cars break down and must be repaired, and a car that is difficult or impossible to repair will cost its owner large sums of money. Software doesn't break down (though online services do) but for other reasons modification is a high priority.
Perhaps short-lived buildings don't need to be easy to modify, especially if the architects have a very good understanding of the needs of the users over their lifetimes. Often that is not the case, though, and Christopher Alexander was famous in large part because much of his career was devoted to figuring out how to enable inhabitants of buildings to modify them more easily, so that their needs would eventually be met even if the architects guessed wrong decades in the past. Centuries-old stone farmhouses exist, too, and ease of modification is crucial for them; if they cannot be modified they cease to function in only a century or two at most.
Whatever the goal of your software, it is crucial for the people who are modifying it over time to achieve that goal to be able to understand it.
A genius architect/Formula 1 engineer can design a building/engine that fits all the requirements astonishingly perfectly, but if the builders have difficulties understanding it, or later contractors can't figure out how to maintain or fix anything, then it's only a perfect design in theory and an awful design in reality. It's not a nice-to-have to make people's lives a little easier, it defines the success of the project. The genius architect/engineer can insist that the complex design reflects the underlying domain as much as they want but at some point they will have to back that up to someone else who isn't a genius.
Obviously, writing code such that a first year comp sci student can understand what's happening and can start contributing immediately is absurd, but at the same time nobody builds anything in a vacuum. There's a certain legibility required within any context you're designing something for.
Most people aren't building Formula 1 cars. Buildings are a better analogy: they are designed to be maintained. You can replace a door handle without replacing the door or the wall, you can turn off the power to different sections to do repairs. Dangerous or complex parts are labelled, moved into their own rooms or cupboards, and locked.
This is what the soft in software means. It needs to be able to be adapted and change with its requirements.
My favourite story from a previous job was working with high-speed scanners, OCR, data quality, typo correction - that kind of thing.
The pipeline did its job well enough. But later we got a new contract where we accepted email submissions (where the customer had scanned stuff themselves). The guys couldn't hook that into the pipeline, so they set up a new pipeline - to print out the emails so they could then be scanned into the existing pipeline.
Writing software is more akin to building an engine factory than a single engine. At least, much of business software is used over a long period with lots of changes needed. Maybe writing a single game is more comparable to the race engine.
This explains everything that's wrong with modern software.
When you design a Formula 1 race car engine, the purpose of engine design is not to "make the engine easier to modify". It's to win races. And that depends on the race - a funny car engine, a formula 1 engine, a LeMans engine, Nascar engine, etc, are all different because the races are different.
Another example: when you design a building, the goal isn't to make it easier to understand the building. The goal is to meet the requirements of the building, its uses, requirements, environment, etc. Sometimes a better building is just more complicated, and making the architect or builders' jobs easier, while nice, isn't the goal.
Some things aren't supposed to be easy to understand, because ease of understanding is not the goal of the thing. Focus on the real goal of the thing, and achieving that; don't get distracted by ancillary goals.