According to dictionary.com, complex is:
- composed of many interconnected parts; compound; composite:
a complex highway system.
- characterized by a very complicated or involved arrangement of parts, units,
- so complicated or intricate as to be hard to understand or deal with:
a complex problem.
While complicated is:
- composed of elaborately interconnected parts; complex:
complicated apparatus for measuring brain functions.
- difficult to analyze, understand, explain, etc.:
a complicated problem.
Seems pretty similar, right? In fact, 2 of the 3 definitions of complex include the word complicated. And the thesaurus lists them as synonyms for each other. So they’re interchangeable, right?
Sometimes, maybe even often, but not always. One of the biggest areas where they’re not interchangeable is in mapping management processes to use cases. And that’s where the Cynefin framework comes in.
As you can see right there in the chart, the top two use cases are Complex and Complicated. Because how you manage them is very different.
Building a car is complicated. But building a car doesn’t have a lot of trade-offs and decision making (that’s designing a car). Lots and lots of moving parts (literally). And critical paths. Deep dependency chains that might not be obvious at first glance. Getting them out of order means lots of rework and delays. Because we’ve done it so many times and the interdependencies (not dependencies) between steps is very minimal, you can write down the steps, in a specified order, and expect that the process will pretty much follow those steps.
On the other hand, Software development is often complex. It’s the addition of the first part of the definition, the interconnectedness that makes it complex. That fact that it’s recursive. And that you don’t have full knowledge going in. Your choice of domains informs the design of the domain’s API and the act of building that API informs your choice of domains, which changes your API.
Or, working with your customer on what they’re really trying to do, you build a ubiquitous language to describe the work and the expected value. Then you start to implement things based on that understanding. But your language is not perfect, so you learn more about what they really mean as you work. So what you’re building changes. Which clarifies the langage. Which changes what you’re building some more.
So the key is pick the right tool for the job. Using the wrong strategy isn't just sub-optimal, it can make things worse.
And to make software development more challenging, different parts of the solution you’re building land in different quadrants, so it’s not one size fits all. You need to find the right strategy for the different parts of the job and make them work together.