Focus: FunctionalityDescription: Make sure system meets even the unstated requirements!

If you are dealing with a customer with little experience of specifying software requirements, they are likely to only include functional requirements in the specification. They will likely leave out most or all of the non-functional requirements. I’m not talking about things that doesn’t work, I’m referring to a requirements that does not directly specify functionality the system should provide, but instead specify how the system should be, describing a quality of the system. These requirements, even though often unstated, are often crucial to the eventual success of the system.

Most of our other system properties are non-functional in nature, and thus I’m arguing that capturing these non-functional requirements are the key to actually providing the customer with a high-quality system, making it functional by design.

If we’re building a web-shop, there’s likely a requirement to send each order to the warehouse for picking. This is an entirely functional requirement. There could be multiple unstated non-functional requirements hidden in this requirement.

It does not say what delays would be acceptable (from the customer placing the order to it being available for picking in the warehouse) - a non-functional requirement related to performance.

It also might not say anything about the importance of not crashing or stalling upon trying to import an incomplete order (say one without an OK delivery address, or for obsolete items) - a non-functional requirement related to robustness.

This web-shop system can comply completely to the functional requirements, but still infuriate the customer because it doesn’t fulfill the (unstated) non-functional requirements. Consider if it hangs when receiving a single incomplete order, blocking further order processing, needing manual intervention to restart, or if orders from the web-shop are being imported to the warehouse system at a rate far slower than the customers are placing them at the web shop during peak hours, causing unwanted delays in picking.

Obviously, the best would be if all requirements were stated, instead of unstated, but in my experience customers seldom includes non-functional requirements. Of course, that doesn’t stop them from being unhappy when the system does not meet the unstated requirements (“but it’s obvious this shouldn’t take this long!”)

Don’t underestimate the power of the stuffing

Possibly the customer hasn’t even fully considered all these details when you are starting to build the system. Since not all details are known in advance, you (or your team) will have to fill the gaps with some “stuffing”, when you get down to that level of detail. Very often this stuffing corresponds a great deal with any unstated non-functional requirements.

The quality of the stuffing you and your team fill the system with, will be directly proportional to your understanding of the problem (and problem domain), and also to your development experience. Yes, you can ask questions, but if you ask too many, you’ll start getting contradictory answers or annoy your customer who had the hope you would be able to take sensible action on your own.

Domain knowledge and experience will tell you when the customer says one thing but really means another. It will help you decide to make configurable those things that are likely to change (even if the customer didn’t explicitly tell you so). It will help you make the right decisions, and guide your development towards a system that is not merely implementing each requirement, but is functional by design, and where our other system properties have been considered, and added in an amount appropriate for the system you are building.

The importance of experience and domain knowledge should not be underestimated! A team of developers, lacking either experience or domain knowledge are likely to get several things wrong at first. A team lacking both are more or less guaranteed to get most things wrong, and are even unlikely to ever get a moderately complex system to a point where it’s mostly working. This is because the inexperienced team hasn’t yet learned to consider the unstated non-functional requirements, but hopes to achieve full functionality by more or less independently working their way through implementing the requirements to the letter, one by one.

This reminds me of an assignment in programming class at university, where we were implementing a text editor, and had a requirement to warn the user of unsaved changes if he tried to exit. Some students then simply let the editor exit with a message like “Warning, you had unsaved changes” printed on the console.