Placing complexity: Localized Complexity Zone
Another semi-post morten talk that we had today had to do about complexity. A co-worker has just found my windsor.boo file, and commented on the complexity that it invovles. We had a discussion about this. I aggreed with her that this is indeed complex, but, in over eight months of the project, it was the irst time that someone other than me had to deal with it, and for the rest of the team it Just Worked.
Side note: one of the things that I am going to make sure for the next project is make sure that the entire team has at least a rudimetry understanding of all the important infrastructure pieces.
It got us to a discussion of whatever we can reduce the complexity. Considering what we need to handle in this project, we both agreed that we could not significantly reduce the complexity of the system and that the alternative were either going with a localized complexity zone or spreading it around the entire code base if we removed this functionality.
We couldn't reduce complexity, we could only move it around. By certralizing it in a single place we increased the local complexity of a single part of the application (not the complexity of the code, but the cmpliexity in understanding what is going there, IoC & DI ). But trade off is that we made the rest of the code of the system much easier to work with and understand.
What do you think?
Comments
See Paul Graham's recent "Holding a Program in One's Head" essay.
The objective is to fit the whole project in one's head. However, because most projects are too complex (or heads too small), they won't fit in. Enter "zones", a "zone" being a part of the project that may be quite complex--yet fits in one's head. And, seen from the outside, it is simple enough to understand, so that when you use it from another zone, it uses very little of your precious head space.
Think about garbage-collecting vs. managing memory allocation locally. The garbage-collector itself is quite complex. Yet what you see when you code it that the whole memory management complexity has been moved into some rather simple concepts.
I'd vote for systematically trying to isolate complexity in carefully-designed "complexity zones". Defining the boundaries of a zone can be tricky, though. If it does to little it won't hide enough complexity. If is tries to do too much it will turn into a leaky abstraction--those that seem easy to grasp and then turn into a nightmare.
Zones of complexity seem fine, particularly if its one type of complexity.
On one project I had a similar situation. We were using Castle Windsor, and the config file grew and got ugly. I showed my team some config sections of interest and how they can be changed for their needs, but that was the extent of it. The config file (and Windsor) were a bit of a black box that really only I understood.
In hindsight, I'd say it was a fair trade off. The team had and understanding of what Windsor did, and roughly how to do it, but they didn't need burden themselves with it. So, I'd also vote for certain zones with the label hic sunt dracones. :)
It sounds like a "greater good" scenario. You're adding some complexity in one area of code for the greater good of added simplicity throughout the rest of the codebase. Sounds like a win to me. You just have to be careful to ensure that whoever will be maintaining this code understands the principles that are in place here.
I've talked about this before in terms of lowering the "barrier to entry" of a project. The most important thing when considering complexity is to isolate it to the point where it blends into the background. That's essentially the whole idea around .NET and related managed-code systems, hiding the complexity of things like memory management and abstracting others like I/O so we don't have to think about it on a daily basis.
However, the counter-argument is that hiding complexity can raise your project's "bus factor". That's a term that we use at work, referring to what would happen if someone on the team got hit by a bus. :) A high "bus factor" means that your project is in danger of failure if one of the team members leaves. (It can also indicate that if you have a bottleneck in the design favoring a single person.)
Isolating complexity is good, but the entire team should still be aware of it, even if they don't have to interface with it every day.
Single Responsibility Principle - make a class responsible for being complex ;)
Joking aside, Its better to have a single area that is complex than to have everything complex. As long as you can avoid leaky abstractions anyways.
Comment preview