I was once a member of a product team that developed service layer components for a much larger system. This system was home to lots of business rules. As is typical, over time, business rules tend to multiply.
We eventually had to invent our own language to distinguish between two states -- one inevitable and the other avoidable. We chose to use the words complex and complicated. Arguably, these are synonyms. We needed a way to separate our two interrelated situations.
Situation #1
We build systems that must correctly evaluate access rules based on a particular business arrangement made with the subscriber. While not every arrangement was unique, we accrued many variations over time. We called this reality “complex.” We could do nothing about it unless our business team wanted to renegotiate many subscriber agreements. Impractical and unfeasible.
Situation #2
When we originally designed the system, there weren’t that many subscribers or business rules. You could make the case that we should have foreseen increasing complexity, and to some extent, we did. However, some of the rules eventually didn’t fit our original design model. We had to make accommodations. These accommodations made the system more complicated. While the complexity was incrementally impacted, the system became much more complicated.
Why does this distinction matter? As I mentioned, one is avoidable, and the other isn’t. There are certain types of systems that are complex by nature. Someone who must step in and work on such systems must understand the problem space well enough to navigate its complexity.
Knowing how to develop software and understand the problem space is enough if that system is well-architected and efficiently coded. However, if it was built up over time and has become convoluted, new developers will need much more time to understand the intricacies of the codebase. It’s complicated!
Complicated systems tend to be less of an issue for the people who built them because they have historical context. New team members are forced to learn that historical context to understand the system completely. It is wasted energy. How do you avoid it?
One of the things that makes Agile development practices so hard is that leaders with less understanding of the process see customer value being delivered so much more rapidly, but they don’t understand the price to be paid. That price is sometimes referred to as “refactoring.” Figuring out the timing of a refactoring effort is the hardest thing to do. Wait too long, and you have a huge project. Don’t wait long enough; you are unnecessarily robbing the new product development effort.
I have observed that listening to the developers complain about complexity is the best way to tell when it’s time to refactor. Remember, they use these words interchangeably. Don't expect to hear a difference unless you’ve already agreed upon the different meanings of complex and complicated. New team members might complain about the complexity, but as they learn the problem space, this quickly dissipates. Not so with complicated systems. Even the people who built them complain because they know that it could be better. And, if they’re complaining, it means they recognize how much the system's complicated nature is slowing them down.
Comments