For the last couple of years, my work can be described as nothing but refactoring. And I like it. It’s like taking away the mist surrounding the forest. As you move forward you start to gain a better sense of the code intention and start to detect places where complexity has made its nest.
Complexity is a strange beast. According to Ward Cunningham there are 2 kinds of complexity: empowering complexity (“Well that’s an interesting problem. Let me think about that for a while”) and difficulties (blockage from progress). Does this sound familiar? Where complexity and difficulties come from? To answer this, let’s take a look at the idea of problem space and solution space.
Problem and solution space
As depicted in the picture the problem space is this conceptual space delimited by some rules and constraints. More important it includes the current state of affairs and the desired state. Is inside the boundaries of this space that solutions are born.
As you can see the solutions are not all equal. Obviously, solution 2 is better than solution 1. This leads me to Ward’s definition of simplicity: Simplicity is the shortest path to a solution. Or in the context of our drawing, the shortest path to the desired state. By the same token, we could say complexity is any path that’s longer than necessary.
Now, this may be tricky. Is possible that solution 2 in our example/drawing requires a kind of knowledge that we don’t currently possess. In that case, we can’t even think of that solution. Or we can’t understand it when presented to us. It would take us the extra effort to acquire that knowledge before we can find solution 2 in our problem space. Hence why is important that we try to have a breadth of knowledge of the (mostly thinking) tools out there. But I digress.
So the shortest path, huh? well “shortest” is not the same for everyone.
In this picture, the solution in problem space 2 is complex than the one in problem space 1, not because of the solution itself but because of the problem space.
This “distance” between the initial and desired state is known as essential complexity. No matter what you do, the solutions in problem space 2 will be complex than most of the solutions in problem space 1. It’s just the problem is more complex.
But what about this?
Clearly, problem space 2 is complex than problem space 1. Still, the solution on problem space 1 is complex than the one in problem space 2!
This is known as accidental complexity. It’s the complexity that comes from the solution we chose. Accidental complexity is our fault and is ours to solve.
And what about difficulties?
Well, now we have found where the complexity comes from. But what about difficulties? let’s review the definition:
A difficulty is just a blockage from progress.
mmmm…. from progress? That implies we are already on the path to our destination. Is it the path of solution 1 or solution 2? It doesn’t matter. What matters is that a solution has been selected and we are traversing through it. Keep this in mind as Ward enlighten us once again:
The complexity that we despise is the complexity that leads to difficulty.
That is accidental complexity!
The difficulty is born out of accidental complexity!
So there you have it. I’ve been thinking about this stuff for a while. I still do.
As I continue to refactor code, I find myself understanding more about the solution, and the problem space itself. I believe the main difference between a programmer and a consultant, is that consultants start in the problem space, this means that they have the autonomy to explore and select solutions, whereas programmers are tasked to work on the solution space from the get-go. That being said, most of the time, we don’t know how good a solution is until we code it.
This leads me to the tip of the day: if it’s hard, that is, if the way is full of difficulties, maybe you are taking the long path. Try stepping back and ask yourself “is there another way to accomplish my objective?”