Wednesday, March 28, 2007

Simple is Better: Why Your Complex Requirements Aren't Worth It

Over the last few years, most of my effort has gone into a single software product. This product has a lot going for it, and I've learned a lot in the process. However, the core process of negotiation has become increasingly complicated in release after release. This has been coming to a head for several releases now, but in the current release cycle, it has become more evident than ever that there's a price to be paid for this complexity.

The Price to be Paid
In this last release, we've put some effort into rethinking a few of the base principles of negotiation, allowing the customers to make better use of negotiation after having formed an agreement with our clients.

In order to get to a clear functional requirement that described the business and high-level user-system interactions that was agreed-upon by the relevant stakeholders, it took nearly a month of effort, including a number of cross-functional discussions.

Perhaps some of you are used to working in environments where going from a request to clearly understood requirements often takes a month or longer, I'm not sure. I'm not used to that, and I'm not convinced that it's healthy, even with a long-term product like ours.

Even with that under our belts, the implementation effort has suffered several setbacks as we've dug in, discovering areas of complexity that weren't anticipated. No matter how complex the business side gets, the technical side will always add another level of complexity, and sometimes that level will bite you.

So, having built a system with this kind of complexity, we've lost some agility and some predictability, because it's difficult to make rapid changes and predict the cost of those changes.

How Did We Get Here?
I can't speak for everyone, but I think that we got here for a few reasons: simplicity is hard, and we value features over simplicity.

Some people think simple is easy; it's what you do before you add the complexities. This usually isn't true. One of the things I've learned from experience in writing, building software, and any number of other life tasks is that simple is much harder than complex, short and concise are more work than long and verbose. If you do something the easy way, it'll have rough edges, edge cases and complexities. This isn't always a problem, it's just the way it is.

Smoothing the rough edges, reducing the edge cases, striving for a simple and complete model, tightening the prose, these are all tasks that take additional effort. That effort is the essence of the trade-off. Do you want five features with a few small edge cases, or two fully polished and reconciled ones? In a business environment, this is a tradeoff that a business manager should be able to make, as long as they're well-informed about the aforementioned costs of complexity: that technical and design debt is paid sooner or later, and that it's often sooner than you think.

And then there's time constraints. Given the cost of complexity, it's not uncommon that a business will make the tradeoff and decide that "more features" is more important than something as abstract as simplicity. For any one feature, this may be the right decision, but if you make this decision for a significant percentage of your application release after release, you're likely going to find that your costs have risen slowly without you knowing, and that over the long term, you may end up paying more for less.

Worse, this is self-reinforcing.

Self-Reinforcing Cycle
If you've racked up technical debt and you've paid the price of complexity, you'll likely discover that it takes you more and more time to analyze and implement the features. This puts more pressure on the time constraints and causes you to sacrifice even more simplicity.

On the other hand, if you've done a good job of paying down any debt you incur, by paying the price of simplicity, you may find that you've paid a little up-front in order to avoid paying a lot later, that all of your features can be analyzed and developed quickly. This reduces the time-pressure, and helps you to continue to strive for simple solutions.

How do I Avoid This? How do I Get Out?
The easiest way to avoid this is to not incur design debt and technical debt. Seek simple answers to complex problems, and don't give up until you find them. When you need, as a business, to incur a little debt, make sure you pay it back as soon as you can. Finally, having built up significant debt, don't be afraid to take a step back. It's only going to get worse, so you might as well deal with it now.

Are your projects complicated? How do you deal with it?


Ricky Clarkson said...

Is it possible that complex requirements are just multiple simple requirements?

If Joe wants X, Jim wants Y and John wants Z, instead of trying to get them to compromise, perhaps you could implement all three, and wait for the new requirement of "unify these". It might never come.

If you could give more concrete requirements, perhaps the discussion would be better.

Geoffrey Wiseman said...

In this case, I haven't found a way to break it down much more than we already have into pieces that still individually deliver value.

Unfortunately, the same complexity that makes it difficult to analyze and implement the feature makes it very difficult to describe in a compact manner.

The title is perhaps a little misleading; the new requirements are not SO complicated, but they relate to parts of the system that are already so complicated that it's like a puzzle just trying to figure out how to put in something that sounds like what is desired without breaking previous desires in a significant way, let alone implement.

I'll ponder it a little; if I can find a way to give a more concrete example in a concise way that people might actually read, I will.

tCodex said...

Interesting article. I believe you are on the right track. I work for a state gov agency in Az and just finished a recent project where I barely dodged the "let's do great amounts of documents" bullet.

Since I was the sole developer (it's good to be king!) I deemed it my job to make sure that I put a lot of effort up front into 'cleaning the edges' and making the code simple up front at the expense of time up front - it has been well worth it - changes I make now are much easier than the previous version of the project and I actually delivered the project on time.

Anyway, not tooting my horn just kind of confirming that I think you are on the right track as do many others out there.