Remember the real world
At one time or another, each of us has become absolutely spitting mad because we've read an article or a book or seen a presentation that we felt was incomplete. In each case, somebody discussed some aspects of a set of technologies, solutions, and options, but then ignored a crucial issue: non-functional requirements.
Granted, functionality is important. After all, if you can't show that the system you're building does what you want, then who cares? But while it's all well and good to come up with a new, clever, simpler, prettier, or more elegant approach to solve some problem, if you don't consider non-functional requirements, then your solution may actually be useless in practice.
We've all seen plenty of reasonable solutions that turned out to be absurd when you actually considered how to make them work in the real world of big systems being managed by real people who are very busy. The cause of these disasters is discounting or ignoring the system's non-functional requirements.
Non-functional requirements are those that don't necessarily address "I want my system to do this," but instead address "How do I make this system work in the real world". Some of these real world issues that you rarely hear people mention are:
High request volumes for online systems: Lots of users, all at once!
Overburdened administrators that have to deploy your applications: In the real world, an administrator will deploy each application more than once - and then have to monitor each one after deployment.
Administrators that make mistakes: Most of us are human, after all! While it's theoretically possible to perform 100 manual deployment steps perfectly, in the real world that just doesn't happen.
Annoying script kiddies and real, honest-to-goodness crackers that attack our systems: Security matters!
So, what are non-functional requirements? There are a number of good definitions available, but we'll start by looking at the ISO 9126 list of Software Characteristics; aside from (of course) functionality, these characteristics include:
It's not enough to show that your system can do something once. If a system does not work reliably (for instance, while under load, or when systems fail, and so on), then it's not going to serve the customer's needs.
Some questions to ask yourself are:
- Can this run reliably even when there are hardware failures?
- What about replication and failover scenarios?
- Is manual intervention needed, or can the system failover automatically?
- Will implementing reliability negatively impact performance?
- How much will implementing reliability cost?
Some special aspects of reliability to consider are:
Security: Assume that attackers are out there. How do I know that the user of the system is who they say they are and only give them access to authorized functions? How do I protect my system from attack? Think about network attacks, machine attacks, and even attacks from within your own systems.
Transactionality: How is the system designed to preserve the ACID properties of a unit of work? This is especially important if multiple independent subsystems are involved in your design (as is the case with Web services and SOA). Do not assume that two phase commit is always possible.
If your users cannot easily access your product from the channels they have available (like the Web), then what good is it? This is sometimes considered part and parcel with functionality (or should be in a perfect world), but is often ignored to the peril of the project as a whole. Some issues to consider here are:
- Are you placing undue burdens on your users (for example, requiring special browser versions)?
- Has the system been designed according to a Model-View-Controller architecture to make multiple user interfaces possible? If so, how are they bound together?
- Is the interface inherently stateful while the functions are stateless (or vice versa)?
The most functional, reliable, and usable system will ultimately fail if it does not make efficient use of its resources (like processors, memory, and disk space). We've often found it useful to split efficiency into two sub-areas, both of which deserve consideration:
Performance: How well will this system perform? Is it just plain slow? Can the system meet its response time goals? Is the application designed for performance? Do you take advantage of caching?
Scalability: If the system seems reasonably fast in the small, how well will it scale with thousands or hundreds of thousands of activities per second, minute, or hour? How is it designed to meet the throughput goals? Can I replicate the systems to achieve linear scaling? Are there bottlenecks (like a common database)?
This is a vitally important requirement because if the developers, administrators, and operators cannot figure out how to manage the application, then it won't live past the first release. Let's assume you are an administrator tasked with having to run this thing. How do you configure it? How do you monitor it? What if you have to do things many times (for example, install dozens of applications)? Do you have a reproducible deployment process? Can you automate repetitive tasks to make it feasible in the large
Although last on the list, it's certainly not the least important. For instance, how are standards employed to provide some form of platform neutrality? Do you have a plan for moving applications to the latest and greatest version of your application server? If not, what do you do when the vendor withdraws support for that version? Similar issues come up if your project is based on open source. If you have to rewrite the whole application every time somebody comes up with a better mousetrap, no one will beat a path to your door.
In a perfect world, we would hope that every article, paper, Redbook, slide presentation, and system design would address these important issues head on. They matter. Tradeoffs almost always have to be made that should be explicitly called out so that you can determine if a specific design will meet your needs. If you are reading something that doesn't address these issues, consider this our warning - something important has almost certainly been overlooked. If you are an author, consider this our plea: don't ignore these issues!