In my last column, I initiated a discussion about holonic software development, a development method that stresses innovation over process. It is my belief, as I stated in last month's manifesto, that holonic software development has the potential to allow developers to achieve extraordinary results. This does not, however, mean that I advocate the total elimination of process. My philosophy with regard to process can be summed up as follows:
With too little process it takes extraordinary people to do ordinary things;
with too much process even extraordinary people can't do extraordinary things.
I'll build on my discussion of holonic software development and the application of processes this month. In particular, we'll talk about requirements gathering, the foundation of any software development cycle, and how a holonic approach -- one that dynamically implements a number of processes and methods throughout the development cycle -- can strengthen your requirements gathering procedures.
The problem of software invisibility
The difficulty involved in conceptualizing new software applications varies from project to project. While the requirements for some projects are straightforward -- perhaps as simple as applying a new technology to a well-known domain -- others may be more difficult. As we continue to apply software technology in uncharted areas, the act of creating requirements for software systems becomes one of conceptual innovation. This innovation is not only a difficult mental exercise for the individual, it is difficult to communicate to the larger development group.
Frederick Brooks called the property of new software applications that makes them hard to conceptualize and specify software invisibility. While other domains such as hardware have a physical presence, software does not. The results of a software application may be observable or measurable but the representation of systems is mental in nature. This is one of the many reasons that we create and rely upon models of software. A model lends a physical dimension to the software that allows us to better understand and communicate its direction.
At the heart of any software modeling effort is requirements gathering. The choice of requirements gathering process to implement depends on the greater context of the development project. This context may be found in the requirements gathering process itself or in another complimentary model. In some cases, the context may even be found in the deliverable. We can always tell where the requirements context of a system resides by looking at the places where we explore different requirement possibilities. Requirements context is the area where we fight software invisibility.
Choosing the right process for the job
The requirements gathering process you choose to implement can have an enormous impact on the success of your software development project. Because requirements gathering is the foundation of the development cycle, an ineffective or ill-chosen requirements gathering process greatly increases the probability that your project will fail. This can lead to rigid adherence to a known process, generally associated with a single, favored software development method.
The requirements gathering processes we'll explore here are drawn from three leading software development methods: the Rational Unified Process (RUP), Feature-Driven Development (FDD), and Extreme Programming (XP). Each method provides a wealth of excellent tools to assist in the requirements gathering effort. In keeping with the holonic development method, we will focus more on the necessary parts -- the requirements gathering process associated with each method -- than on the whole of the method itself. Out of this, we'll see if we can assemble a more dynamic and mutable requirements gathering procedure. Before we move on, take a moment to read the sidebar "Ten best practices for holonic software development" to see how the holonic approach encompasses much of what we already know in theory.
The four most common requirement gathering processes are the traditional software requirements specification (SRS), use cases, features, and user stories. In the sections that follow, we'll look at each of these processes, paying special attention to the requirements context -- that is, the appropriate circumstances for maximizing the value that each one provides and the unique dynamics that each one brings to a development project. See Resources for details on the application of each process outlined below.
The software requirements specification
The software requirements specification (SRS) is one of the oldest requirements gathering processes. Known informally as the "shall statements," the traditional SRS exists in many forms and is still required today for contract work in numerous fields. The SRS was the dominant requirements gathering method for many years.
The idea behind the SRS is to create a solution space -- that is, a space in which the development team has set goals but a good amount of latitude in the order and nature of activities by which it achieves those goals. As a result, an SRS typically does not try to specify a single solution, but rather defines a family of possible solutions. The development team then has enough flexibility to innovate efficient ways of solving the problem for which a system is being created.
Flexibility is a strength as well as a weakness of the SRS. If a software development team is proficient in the domain for which it is creating a system, it can easily use the SRS to maximize innovation in that domain. In an age when development teams routinely work in domains that are foreign to them, however, the traditional SRS may fall short as a requirements gathering process. The team may not understand the steps that a typical user takes when attempting to deal with normal conditions in a given domain. As a result, the team may specify and create a system that is not optimal for the user community.
The traditional SRS is best suited to domains that are well understood and to development teams that are familiar with the domain in which they are working -- or to development environments where outside domain expertise is easily accessible. The SRS allows very few techniques for adjusting the solution space to manage change in the system.
In contrast to the solution space approach espoused by the traditional SRS, use cases describe the sequences of actions that users perform as they interact with a system. In some sense, the use case is path- or goal-based. It conveys the series of actions a user must initiate as he uses the system to resolve problems. For example, in a Video Rental use case, we describe what happens when a user interacts with a video rental system.
Use cases reflect all of the events that can happen to us as we attempt to use a software system to achieve a goal. Because most software systems support many goals, most use case models will consist of many use cases. The Pay Late Fee use case, for example, describes what happens to a user of our Video Rental system when he encounters a late fee.
The proper level of information in a use case is that which is needed to successfully build the application; this will vary according to the circumstances. If domain experts are part of the development process, the use cases may only sketch paths through the system. If domain experts are not part of the project, the use case will be required to supply more information. The use case is an excellent process for communicating requirements. Like the traditional SRS, however, use cases are better suited for domains that are well understood. A use case can undergo a certain amount of change, but other processes are better suited to absorb change.
The following use case is used to define optimal paths for a customer in an automated (Web-based) video rental scenario.
Use case name: Rent Video
Unique use case ID: VS-01
Primary actor(s): Customer
Secondary actor(s): N/A
Brief description: This use case describes the interactions that take place when a customer rents a video on the Web.
Trigger: The customer selects a title from the catalog.
Pre-conditions:
- The customer must have an active account.
- The customer meets the age requirement of the video rating attached to the catalog.
- The catalog has been provisioned with titles.
Flow of events:
- The customer browses through the catalog and selects a title.
- If the title is available, the system adds the media for the title to the cart and the media is pending rental.
- When the customer is finished selecting media, he places the order. To place the order, the customer is authenticated and the account is validated. The cost of media is debited from the account. The media in the cart associated with the order is changed to Rented.
- The system acknowledges the order.
Post-conditions:
- A new order is created for the account.
- The inventory is modified to reflected the rented videos.
- The system has debited the account and credited the business for the cost of the video rentals.
Alternative flows and exceptions:
- The title is unavailable: the customer must make another choice.
- The account is invalid due to unpaid late fees: see Pay Late Fees use case.
- The account is invalid due to an invalid credit card: the system prompts the customer for a valid credit card.
Features are brief statements of the desired functionality of a system. A feature has the form:
<action> the <result> <by|for|of|to> a(n) <object> |
An example feature might be:
Forecast the total of quarterly sales. |
The feature-based approach works best when each feature is kept small. The ideal feature is one that can be implemented by a team in two weeks or less.
Features are organized in groups called feature sets. A feature set contains features that describe a given goal or area. A feature set and its features are merely outlines of the requirements. As a mechanism for describing requirements, features must be combined with additional context.
In the Feature-Driven Development method, context is elaborated between feature sets and a color-coded class diagram called the domain neutral component. The domain neutral component is a semantic template that depicts common relationships found across domains. The domain neutral component consists of moment-intervals, roles, subjects (parties, places, or things), and descriptions. Moment intervals are those elements of the domain that are transitory, such as an order in an order fulfillment system. A role is a user who interacts with the system and must be known to the system. Subjects are the elements that form the domain. Descriptions are abstractions that collect meta-information about those objects. Figure 1 is a domain neutral component for a video rental scenario.
Figure 1. Domain neutral component for a video rental scenario

As a requirements gathering process, Feature-Driven Development is very flexible, lending itself to change management throughout the development cycle. This process lets you easily examine and keep track of the number of new, changed, and removed features as the project proceeds. Because features are generally small, making changes to existing features or adding new ones is unlikely to demand extensive rework at the project level. Features also help to combat software invisibility, because new features may be uncovered as a result of tracing interactions between the system entities in the domain neutral component.
Features can be used to communicate requirements between individuals who are familiar with a given domain. Used in this manner, the feature-based approach is probably the most parsimonious requirements gathering process. Features may, however, rely too heavily on domain expertise, a luxury many development teams do not have.
User stories are small descriptions written on index cards, as shown in Figure 2.
Figure 2. Point of sale user story

User stories tend to contain more information than features, though this is not a requirement. Under the Extreme Programming method, user stories require an on-site customer to provide partial context. The on-site customer describes the ideal system to the development team. The team then builds the system in small increments, giving the customer ample opportunity to view the results at regular intervals. The customer "sees" the deliverable and may suggest modifications to the system through new user stories. Full context is realized by the combination of feedback from the on-site customer and the incremental progress and delivery.
User stories are best for dealing with projects where the risk of software invisibility is high. Like features, they are small enough that they can be easily changed. Because their context is based on the working system and the customer, they are discarded once implemented or no longer valid. Not every project can include an on-site customer, however, so not every project is suited to user stories. This approach loses many of its benefits without the customer interaction.
Each of the requirements gathering processes we've discussed in this article has its merits when used in the proper context. As this discussion shows, however, no requirements gathering process is ideal for every context, or even necessarily complete in itself. Recognizing the essential incompleteness of a single process or activity, and broadening the spectrum of available solutions to mitigate that incompleteness, is central to the holonic software development method.
The sidebar "Ten best practices of holonic software development" discusses modularity. Modularity allows one activity to be substituted for another one when the two activities serve the same purpose. When substituting one requirements gathering activity for another, it is important to take the requirements context into account. Changing activities midway through the development cycle could easily introduce a new set of dynamics to the project. Without a sense of context, this move can be disastrous. When carefully planned and executed, however, introducing new activities can help to create new dynamics, thus advancing the success of the project.
Next month, we'll talk about modeling a Web services infrastructure. As we investigate this emerging area of software development, I'll provide more concrete examples of the techniques and best practices we've discussed over the last two columns, so stay tuned!
- Jeff De Luca provides an excellent introduction to the origins of FDD, with his article, "The
original FDD processes."
- Newcomers to XP might want to start with this thorough overview: "XP distilled" by Roy Miller and Chris Collins (developerWorks, March 2001).
-
Extreme Programming.org, a great resource for XP enthusiasts, offers a slightly expanded introduction to the role of user stories in the XP development process.
- User-centered design (UCD) is a requirements gathering and feedback process much like user stories, but with a broader scope. Find out how you can use the cheap, low-overhead "Fly on the wall" approach (developerWorks, August 2001) to learn what your users want.
- Read all the Java Modeling columns (including last month's Holonic Software Development Manifesto) in the Java Modeling archive.
- Find more Java resources on the developerWorks Java technology zone.

Granville has over a decade of experience in the object-oriented community. He is coauthor of the Advanced Use Case Modeling series and has presented tutorials at various object-oriented technology conferences worldwide. His hands-on approach to object-oriented development has been the result of his work with companies that range from startups in the very early stages to some of the most established software giants. He is currently teaching seminars, tutorials, and classes in agile processes, methodology, and Java technology, as well as mentoring and helping to deliver aggressive projects. Contact Granville at rmiller@togethersoft.com.




