Making Requirements Reusable
Written by Karl Wiegers and Joy Beatty
Reuse is an eternal grail for those seeking increased software productivity. People think most often in terms of code reuse, but many other software project components also have reuse potential. Reusing requirements can increase productivity, improve quality, and lead to greater consistency between related systems.
Reuse is not free, though. It presents its own risks, both with respect to reusing existing items and to creating items with good reuse potential. It will likely take more time and effort to create high-quality reusable requirements than to write requirements you intend to use only on the current project. In this article, adapted from our new book Software Requirements, 3rd Edition (Microsoft Press, 2013), we describe some of the approaches an organization should consider taking to maximize the reuse potential of its requirements.
Just because a requirement exists doesn’t mean it’s reusable in its present form. It could be specific to a particular project. It might be written at too high a level because the BA could safely assume certain knowledge on the part of the development team or because some details were communicated only verbally. A requirement could be lacking information about how possible exceptions should be handled. You might have to tune up the original requirements to increase their value to future BAs.
Well-written requirements lend themselves to reuse. The steps you take to make requirements more reusable also increases their value to the project for which you originally write them; it simply makes them better requirements. Reusers need to know about dependencies the requirement has on others, as well as other requirements that go with it and that might also be reused, so that they can package sets of related requirements appropriately.
Reusable requirements must be written at the right level of abstraction and scope. Domain-specific requirements are written at a low level of abstraction. They are likely to be applicable only in their original domain. Generic requirements have broader applicability for reuse in a variety of systems. However, if you attempt to reuse requirements at too general a level, you won’t save much effort because the BA will still have to elaborate the details. It’s tricky to find the right balance between making reuse easier (with more abstract or generalized requirements) and making reuse pay off (with more detailed or specific requirements).
Figure 1 provides an example. Perhaps you’re building an application that includes a user requirement to accept credit card payments. This user requirement would expand into a set of related functional and nonfunctional requirements around handling credit card payments. Other applications also might need to take payments by credit card, so that’s a potentially reusable set of requirements.
Figure 1. Generalized requirements offer greater reuse potential.
But suppose you could generalize that user requirement to encompass several payment mechanisms: credit card, debit card, gift card, eCheck, and electronic funds transfer. The resulting requirement offers greater reuse potential in a wider range of future projects. One project might need just credit card processing, whereas others require several of the payment processing methods. Generalizing an initial user requirement like this—from “accept credit card payment” to “accept payments”—could be valuable even on the current project. Even if the customer only asked to handle credit card payments initially, users might really like to accept multiple payment methods either now or in the future.
Choosing the right abstraction level for requirements can pay off during construction, as well. On one project that had exactly this need for multiple payment methods, generating clear requirements and rules for each case revealed both commonalities and distinctions. Independent from future reuse possibilities, building the higher-level abstractions contributed to easier design and construction.
That’s the good news. The bad news is that it will take some effort to generalize the initially presented requirement. That’s the investment you make in reusability, anticipating that you will recoup the investment—and more—through multiple, future reuse instances. It’s up to you to decide whether to simply place today’s requirements into a shared location for possible reuse or to invest effort to improve their reusability on future projects.
A colleague offered a cautionary tale of how to reduce the potential value of reuse by writing excessively detailed requirements. A team tasked with writing requirements for a new project was obsessed with reuse. The BAs thought that if they documented all of the details for each requirement separately, then they could be reused. They ended up with more than 14,000 requirements! The repository contained entries that should have been just one requirement but had been structured as a parent with multiple child requirements, each giving a specific detail about the parent. Requirements this detailed were relevant only to that one application.
This volume of requirements also made the testing cycle much more difficult, leading to daily complaints from the testers. It was taking them much longer than expected to write test cases because they had to wade through such a vast quantity of requirements. The testers had to document the requirement ID in their test cases to ensure that test coverage of the requirements was achieved for traceability, but the number of traces on this many requirements became difficult to manage. In addition, the requirements underwent extensive change; they never did fully stabilize. All of these factors led to the project being deployed a year late, without producing the desired collection of reusable requirements.
In an ideal world, your business analysts would always write requirements that have grand potential for reuse across a multitude of related projects, thereby saving your organization countless hours and vast sums of money. In reality, you need to look for those certain requirements that start out with some reuse potential and massage them into a form that maximizes the possibility that a future BA will find them useful.
Author Bios: Karl Wiegers is Principal Consultant at Process Impact, www.processimpact.com. Joy Beatty is a Vice President at Seilevel, www.seilevel.com. Karl and Joy are co-authors of the new book Software Requirements, 3rd Edition (Microsoft Press, 2013), from which this article is adapted.