Complex Requirements

by Krishna on November 1, 2007

Of the many differences that separate a simple software project and a complex one, this one is the most critical: A complex project has requirements that do not fit into one human brain. Many people understand this concept vaguely, but never understand it deeply or consciously. So let us analyze what this means.

A complex project has data and functional relationships that are many magnitudes numerous than a simple project. This is not necessarily related to the number of features that an application has. Nor is it necessarily related to the number of screens, reports, tables or lines of code. For example, a Garbage-In, Garbage-Out application with 5 input screens and 1000 canned reports may be less complex than one with 20 input screens and 30 dynamic reports, even though the former is a larger application.

The complexity comes from how interdependent the various modules the application are. Most of us are familiar with the concepts of coupling and cohesion in software design. But those concepts are also relevant to requirements management. Any requirement has the potential to affect the behavior of another requirement in the system. The more they actually affect each other, the higher the coupling between requirements in your proposed system.

Let us take a billing system. Every transaction affects AR, AP and associated financial statements. Now, let us add the requirement of managing a clerical error. Can the transaction be canceled? How long after the transaction can it be canceled? What happens if the error is discovered after a quarterly reporting period? What do you do about past reports? Introducing one seemingly simple requirement has affected many modules within the application.

Let us take an opposite example. When Google added a new Presentation module to their Google Docs, it hardly affected the rest of the system, except a name here and a link there. Although the Presentation module is very complex in itself, it did not affect the functionality of the rest of the system in any significant way. Now, Google can continue adding new modules and it won’t have a problem until it attempts to do what Microsoft Office does: Embed one document type in another document.

In a complex project, it is very difficult to understand all the complex rules involved. Consider 3 dependent events, the order of which is unknown. We have to consider 6 different permutations of the events. 4 events result in 24 permutations. 5 events result in 60 permutations. In a real system, the different transactions affecting the system result in an incredibly high number of possible permutations.

With a simple level of complexity, it is easy to keep all the system requirements in your head. Many small projects operate that way, successfully. As the complexity increases, you have to rely on external methods like some form of documenting requirements. Take your pick — software requirements documents, wiki pages, user manuals, test cases, etc. The primary symptom of non-documented requirements is the increasing number of regression bugs. If you ever have to tell someone, “This was working before. Now you broke it”, then it usually means that the other person does not know what the requirement is.

With complex requirements, you cannot rely on documented requirements alone. The reason is that since requirements affect one another, the person documenting them has to continuously cross-link and/or duplicate requirements so that it is evident to the developer what is happening. For example, in our billing system example, when we document “canceling a transaction”, we have to link to many other sections in the requirements. This is practically difficult and usually error-prone.

One strategy is to reduce permutations by enforcing some constraints in real life. For example, many billing systems do not allow cancellations. Instead, you have to put another entry — a negative entry. This means that functionality used to handle regular entries can be re-used, reducing the complexity. However, this may be problematic, because it creates greater hurdles for end users. Also, when your rules are defined by government regulations, you don’t have much leeway in changing them.

When you are building a system from scratch, another strategy is to build incrementally. Build a core that is less complex. Make it stable. Add a complex requirement. Stabilize the system. Repeat until you are done. Sometimes, you realize that a requirement is so incredibly complex that you simply cannot get your arms around it and it is consuming too much of your time. The best thing you can do is abandon that requirement after negotiating with your customers or doing more market research.

If your complex system already exists and you are adding new requirements, my heart goes out to you. It is a thankless job. 99% of the time, proper documentation is missing. Customers do not appreciate how much time you have to spend understanding the application. The benefit of any change is heavily outweighed by the outrage and anger that happens if you break something, purely because you didn’t know about it.

That brings me to the final word. Don’t be gung-ho about complex requirements. They are the meanest of all — they have no pity for people mouthing buzzwords or the latest technological fad or management double-speak. Tread with caution. Accept your human limitations. Try to reduce complexity at every step. Analyze every requirement carefully. Maybe, just maybe you may succeed.

Comments on this entry are closed.

Previous post:

Next post: