Professional Documents
Culture Documents
Perhaps the greatest challenge facing the software developer is sharing the vision of the
final product with the customer. All stakeholders in a project-developers, end users,
software managers, customer managers-must achieve a common understanding of what
the product will be and do, or someone will be surprised when it is delivered. Surprises in
software are almost never good news. Therefore, we need ways to accurately capture,
interpret, and represent the voice of the customer when specifying the requirements for a
software product.
Often the customer will present as "needs" some combination of: the problems she has in
her work that she expects the system to solve; the solutions she has in mind for an
expressed or implied problem; the desired attributes of whatever solution ultimately is
provided; and the true fundamental needs, that is, the functions the system must let her
perform. The problem becomes more complex if the systems analyst is dealing with a
surrogate customer, such as a marketing representative, who purports to speak for the
actual end users of the application. The challenge to the analyst is to distinguish among
these four types of input and identify the real functional requirements that will satisfy the
real user's real business needs.
Many techniques are used for eliciting user requirements, all of which attempt to include
the voice of the customer in the product design process. A typical project might employ a
combination of meetings with user representatives and developers, facilitated workshops
(for example, joint application design sessions) with analysts and users, individual
customer interviews, and user surveys. The use case approach is an especially effective
technique for deriving software requirements, analysis models, and test cases.
Use (pronounced "youce," not "youze") cases were introduced as part of an object-
oriented development methodology by Ivar Jacobson in Object-Oriented Software
Engineering: A Use Case Driven Approach (Addison-Wesley, 1992). More recently,
Larry Constantine and others have extended the concept into a general technique for
requirements analysis and user interface design. Each use case describes a scenario in
which a user interacts with the system being defined to achieve a specific goal or
accomplish a particular task. Use cases are described in terms of the user's work
terminology, not computerese. By focusing on essential use cases, stripped of
implementation constraints or alternatives, the analyst can derive software requirements
that will enable the user to achieve her objectives in each specific usage scenario.
A software team at Eastman Kodak Company recently applied the use case method to
specify the requirements for a chemical tracking system. Figure 1 illustrates the overall
process we found to be effective with the use case technique and the key deliverables. We
used a series of highly interactive sessions with customer representatives to identify and
describe use cases. Functional requirements, behavioral characteristics, and business rules
fell right out of the use case discussions.
I worked as an analyst with a team of chemists to collect their needs for this application;
other analysts worked with other teams representing different user classes. Members of
different user classes might have the need to use different subsets of the system's
functionality, different vocabularies, different security requirements, and different
frequencies of use of various features. Each user class generated its own set of use cases,
since each needed to use the system to perform different tasks.
The chemist team consisted of one designated key customer representative (project
champion) and five other chemists whose needs differed slightly. Customers having
multiple viewpoints and needs are valuable, to avoid designing a system that is
excessively tailored to meet a narrow subset of the needs of the broader user base.
I began by asking the chemists to think of reasons they would need to use this planned
chemical tracking system, or tasks they needed to accomplish with it. Each of these
"reasons to use" became a use case, which we then explored in depth in a series of two-
hour sessions that I facilitated. We used forms such as that shown in Fig. 2, drawn on a
large flipchart. I prepared one flipchart for each use case prior to the group sessions.
For each use case, we stated the goal that the user needed to accomplish-one reason
someone would use this application. We also noted which of the various user classes we
had identified for this application (chemist, technician, stockroom staff, purchasing
department) would be interested in each use case. Estimating the anticipated frequency of
execution for each use case gave us a preliminary indication of concurrent usage loads,
the importance of ease of learning versus ease of use, and capacities of data storage or
transaction throughput. We could also identify the relative priority of implementing each
use case at this stage. The sequence in which users identify candidate use cases suggests
an approximate implementation priority.
We spent the bulk of each workshop exploring the actions the user would expect to take
with the computer for a specific use case, and the possible responses the system might
then generate. As the chemists suggested user actions (or inputs) and system responses, I
wrote them on sticky notes and placed them under the appropriate heading on the
flipchart form. Often, a system response would trigger further dialog with the computer,
necessitating additional user input, followed by yet another response. The movable sticky
notes made it easy to revise our initial thoughts and to group together pieces of related
information as we went along.
By walking through individual use cases in the workshops, we drilled down to the
fundamental customer needs the system had to satisfy. We also explored many "what if"
scenarios to reveal exception and decision situations the system must handle. New use
cases sometimes came to mind as we worked through those that the chemists had already
suggested.
Some of the pieces of information elicited in the workshops were not really functional
requirements. Instead, they were business rules about the system and the work processes
it supported, stating such policies as: "Safety training records must be up to date before a
user can order a hazardous chemical" and "A purchasing agent can modify a user's order
only with written permission from the user." We documented these business rules
separately from the functional requirements, and then communicated them to the project
champions of the other user classes, who had their own, sometimes conflicting, business
rules. Discrepancies were reconciled in a meeting between the analyst team and all of the
project champions.
We found that the use case strategy of asking "What do you need to accomplish with this
system?" kept us focused on visualizing how the application ought to perform some
function. More open-ended discussions that begin with "What do you want this system to
do?" can lead participants to suggest features that are not necessarily linked to specific
user tasks. The distinction between these two questions is subtle, but important. The use
case angle emphasizes user objectives, not system features. Use cases provide a way to
decide what features are necessary, as opposed to building in specific features and hoping
they let the users get their work done.
After each workshop, I took the flipcharts festooned with sticky notes to my office and
began to extract requirements from each use case. Most of these requirements represented
those software functions that would be needed to allow a user to execute each use case. I
began documenting the requirements and business rules in a structured software
requirements specification, or SRS, which grew from week to week.
Within two days after each workshop, I delivered the preliminary SRS to the chemist
team members. They reviewed the SRS changes informally on their own, in preparation
for the next weekly workshop, at which we discussed problems they found during their
review. The next iteration of the SRS incorporated any necessary corrections, as well as
new requirements extracted from the latest use case discussion. By making multiple
passes through the growing SRS in this way, we created a much higher quality product
than if we had waited until the complete SRS was done to begin the review process.
For certain complex use cases, we also drew dialog maps, or models representing a
possible user interface at a high level of abstraction. A dialog map is a form of state-
transition diagram, in which each dialog element-screen, window, or prompt-is shown as
a state (a labeled rectangle), and each allowable navigation pathway from one dialog
element to another is shown as a transition (a labeled line). We used dialog maps to
represent the possible sequences of human-computer interaction in several scenarios
related to a specific use case, without worrying about details of screen layout or
interaction techniques.
After all the information was translated into structured textual requirements
specifications, business rules, and structured analysis models, we were able to take
another important step: deriving test cases.
Writing functional test cases is a great way to crystallize the fuzzy image in your mind
about how a program should behave. Deriving test cases from our use cases proved to be
easy, since we had already been thinking about how the user would interact with the
program to accomplish various tasks. Each test case represented one specific scenario of
interaction with the system, within the context of one of the essential use cases. The test
case might result in a successful transaction, or it could generate an anticipated error
response of some kind.
Using the requirements specification to provide details, we developed test cases without
the chemists ever having sketched out screens or discussed the exact database contents.
Our general concept of the sequence of events that characterized a use case provided
enough detail to permit writing many test cases. If you can't readily think of test cases
that demonstrate your understanding of a use case scenario, you haven't adequately
clarified the vision.
Having test cases in hand this early in the development process provided several benefits:
We could "test" parts of the specification long before it was complete by having
the chemist group walk through the test cases to find any changes that we needed
to make in our specifications so that the tests could be executed.
We could use the test cases to "test" the dialog map. As we walked through the
conceptual test cases derived from the SRS, I traced the corresponding paths on
the dialog map with a highlighter pen. This revealed allowable execution paths we
had missed in the test suite, as well as identifying test cases that could not be
"executed" according to the current dialog map, indicating errors in either the
dialog map or the test cases.
We could establish traceability between each test case and the requirements it
addressed. Any requirements that were not covered meant writing more test cases;
any test cases that relied on functions not present in the requirements document
showed that some requirements were missing.
We could use the suite of test cases to evaluate commercial products that might
meet the needs of the project, enabling us to decide whether to build or buy. We
simply had to walk through the test cases with an evaluation copy of the
commercial package to see which cases it handled and which it did not. The test
cases that mapped to top priority use cases were the ones to focus on.
Developing test cases early in the project reinforced our fundamental philosophy that
quality activities must not be left to the end of the development cycle, but should
permeate the entire project from the outset. (For a related example, see "Reduce
Development Costs with Use-Case Scenario Testing," by Scott Ambler, in Software
Development, July 1995.) This use case approach with immediate test case generation
reinforced another valuable lesson. Every time I do any kind of systematic testing, I find
errors in the work products (in this case, in the requirements specification document and
the dialog map), and I find errors in the test cases (such as requirements that were not
covered by the test cases).
Once you have uncovered most of the use cases and assigned priorities to them, you can
devise an implementation strategy. One approach is to use the concept of "threads" to
design and implement use cases incrementally, building new classes or modules as
needed to support the functionality associated with new use cases. A thread is a grouping
of modules or classes that implement a specific set of related requirements, and use cases
provide a natural mapping of requirements to threads. The concept of threads is nicely
explained by Michael Deutsch and Ronald Willis in Software Quality Engineering: A
Total Technical and Management Approach (Prentice-Hall, 1988).
A thorough exploration of use cases before doing any serious construction will help you
avoid building a fragile, incoherent architecture, with new classes or functions being
slapped together willy-nilly. Select a construction sequence of threads to implement
critical use cases and supporting functionality first, but design a sufficiently robust and
extensible architecture to permit incremental assembly of additional use cases over time.
This approach will deliver the most essential functionality to your customers as early as
possible.
Two less obvious benefits are derived from the use case method. First, the act of
developing use cases helps analysts gain an understanding of the user's application
domain. Second, it helps avoid superfluous requirements. When approached with the
question, "What do you want the system to do?" customers are tempted to add features
that seem like good ideas and might be useful some day. From the use case angle, though,
every requirement directly supports a specific task the user needs to accomplish with the
help of the computer.
It may be a little confusing when people start thinking in terms of use cases. Suggested
use cases may still really be lists of features, or desired behaviors, or attributes. However,
you should be able to map each of these characteristics to one or more existing use cases.
If you cannot, perhaps the features or behaviors described are unnecessary. A more likely
possibility is that some use cases were missed initially, so these features, behaviors, and
attributes can help illuminate additional use cases.
Use cases constitute a powerful, user-centric tool for the software requirements
specification process. They are applicable whether the product will be constructed using
object-oriented techniques or in a more traditional environment. The perspective provided
by use cases reinforces the ultimate goal of software engineering: to create products that
let customers do useful work.
Acknowledgment
This paper was originally published in Software Development, March 1997. It is reprinted
(with modifications) with permission from Software Development magazine.
Functional Requirements
Functional requirements capture the intended behavior of the system. This behavior may
be expressed as
services, tasks or functions the system is required to perform.
In product development, it is useful to distinguish between the baseline functionality
necessary for any
system to compete in that product domain, and features that differentiate the system
from competitors
products, and from variants in your companys own product line/family. Features may be
additional functionality,
or differ from the basic functionality along some quality attribute (such as performance or
memory
utilization).
One strategy for quickly penetrating a market, is to produce the core, or stripped down,
basic product,
and adding features to variants of the product to be released shortly thereafter. This
release strategy is obviously
also beneficial in information systems development, staging core functionality for early
releases and
adding features over the course of several subsequent releases.
In many industries, companies produce product lines with different cost/feature
variations per product
in the line, and product families that include a number of product lines targeted at
somewhat different markets
or usage situations. What makes these product lines part of a family, are some common
elements of
functionality and identity. A platform-based development approach leverages this
commonality, utilizing a
set of reusable assets across the family.
These strategies have important implications for software architecture. In particular, it is
not just the
functional requirements of the first product or release that must be supported by the
architecture. The functional
requirements of early (nearly concurrent) releases need to be explicitly taken into
account. Later
releases are accommodated through architectural qualities such as extensibility,
flexibility, etc. The latter
are expressed as non-functional requirements.
Use cases have quickly become a widespread practice for capturing functional
requirements. This is
especially true in the object-oriented community where they originated, but their
applicability is not limited
to object-oriented systems.
Use Cases
A use case defines a goal-oriented set of interactions between external actors and the
system under consideration.
Actors are parties outside the system that interact with the system (UML 1999, pp.
2.113- 2.123).
An actor may be a class of users, roles users can play, or other systems. Cockburn
(1997) distinguishes
between primary and secondary actors. A primary actor is one having a goal requiring
the assistance of the
system. A secondary actor is one from which the system needs assistance.
A use case is initiated by a user with a particular goal in mind, and completes
successfully when that
goal is satisfied. It describes the sequence of interactions between actors and the
system necessary to
deliver the service that satisfies the goal. It also includes possible variants of this
sequence, e.g., alternative
sequences that may also satisfy the goal, as well as sequences that may lead to failure
to complete the service
because of exceptional behavior, error handling, etc. The system is treated as a black
box, and the
interactions with system, including system responses, are as perceived from outside the
system.
Thus, use cases capture who (actor) does what (interaction) with the system, for what
purpose (goal),
without dealing with system internals. A complete set of use cases specifies all the
different ways to use
the system, and therefore defines all behavior required of the system, bounding the
scope of the system.
Generally, use case steps are written in an easy-to-understand structured narrative
using the vocabulary
of the domain. This is engaging for users who can easily follow and validate the use
cases, and the accessibility
encourages users to be actively involved in defining the requirements.
Scenarios
A scenario is an instance of a use case, and represents a single path through the use
case. Thus, one may
construct a scenario for the main flow through the use case, and other scenarios for
each possible variation
2001 BREDEMEYER CONSULTING WHITE PAPER 8/3/01 3
of flow through the use case (e.g., triggered by options, error conditions, security
breaches, etc.). Scenarios
may be depicted using sequence diagrams.
Structuring Use Cases
UML (1999) provides three relationships that can be used to structure use cases. These
are generalization,
include and extends. An include relationship between two use cases means that the
sequence of behavior
described in the included (or sub) use case is included in the sequence of the base
(including) use case.
Including a use case is thus analogous to the notion of calling a subroutine (Coleman,
1998).
The extends relationship provides a way of capturing a variant to a use case. Extensions
are not true
use cases but changes to steps in an existing use case. Typically extensions are used to
specify the changes
in steps that occur in order to accommodate an assumption that is false (Coleman,
1998). The extends relationship
includes the condition that must be satisfied if the extension is to take place, and
references to the
extension points which define the locations in the base (extended) use case where the
additions are to be
made.
A generalization relationship between use cases implies that the child use case
contains all the
attributes, sequences of behavior, and extension points defined in the parent use case,
and participates in all
relationships of the parent use case. The child use case may define new behavior
sequences, as well as add
behavior into and specialize existing behavior of the parent. (UML, 1999)
Use Case Diagram
Figure 1. Example use case diagram (adapted from the UML V1.3 document)
The use case structure is graphically summarized in a use case diagram (UML, 1999,
pp. 3-83 to 3-
88), which also shows which actors interact with which use cases.
Actor. Actors, in use case parlance, are parties outside the system that interact with the
system. They may be users or
other systems. Each actor defines a coherent set of roles users of the system can play
(UML, 1999). Cockburn
(1997) distinguishes between primary and secondary actors. A primary actor is one
having a goal requiring
the assistance of the system. A secondary actor is one from which the system needs
assistance to satisfy
its goal.
Architecture. The term software architecture is used both to refer to the high-level
structure of software systems and
the specialist discipline or field distinct from that of software engineering. The
architecture of a software system
identifies a set of components that collaborate to achieve the system goals. The
architecture specifies
the externally visible properties of the components-i.e., those assumptions other
components can make of a
component, such as its provided services, performance characteristics, fault handling,
shared resource
usage, and so on (Bass et al., 1998). It also specifies the relationships among the
components and how they
interact.
Conceptual Architecture. The intent of the conceptual architecture is to direct attention
at an appropriate decomposition
of the system without delving into the details of interface specification and type
information. Moreover, it
provides a useful vehicle for communicating the architecture to non-technical audiences,
such as management,
marketing, and many users. The conceptual architecture identifies the system
components, the responsibilities
of each component, and interconnections between components. The structural choices
are driven by
the system qualities, and the rationale section articulates and documents this connection
between the architectural
requirements and the structures (components and connectors or communication/co-
ordination mechanisms)
of the architecture.
Features. Features are the differentiating functionality of a product. This functionality
may not be available in other
products, or it may not be available with the same quality characteristics.
Functional Requirements. Functional requirements capture the intended behavior of
the system-or what the system
will do. This behavior may be expressed as services, tasks or functions the system is
required to perform.
Logical Architecture. The logical architecture is the detailed architecture specification,
precisely defining the component
interfaces and connection mechanisms and protocols. It is used by the component
designers and developers.
Meta-architecture. The meta-architecture is a set of high-level decisions that will
strongly influence the structure of
the system, but is not itself the structure of the system. The meta-architecture, through
style, patterns of composition
or interaction, principles, and philosophy, rules certain structural choices out, and guides
selection
decisions and trade-offs among others. By choosing communication or co-ordination
mechanisms that are
repeatedly applied across the architecture, a consistent approach is ensured and this
simplifies the architecture.
(See http://www.bredemeyer.com/howto.htm and
http://www.bredemeyer.com/whatis.htm.)
Non-functional Requirements. Non-functional requirements or system qualities,
capture required properties of the
system, such as performance, security, maintainability, etc.-in other words, how well
some behavioral or
structural aspect of the system should be accomplished.
Product Line. Product lines consist of basically similar products with different
cost/feature variations per product.
Product Family. Product families include a number of product lines targeted at
somewhat different markets or usage
situations. What makes the product lines part of a family, are some common elements of
functionality and
identity.
Qualities. System qualities, or non-functional requirements, capture required properties
of the system, such as performance,
security, maintainability, etc.-in other words, how well some behavioral or structural
aspect of the system
should be accomplished.
Scenario. A scenario is an instance of a use case, and represents a single path through
the use case. Thus, one may
construct a scenario for the main flow through the use case, and other scenarios for
each possible variation of
flow through the use case (e.g., triggered by error conditions, security breaches, etc.).
Scenarios may be
depicted using sequence diagrams.
Use Case. A use case defines a goal-oriented set of interactions between external
actors and the system under consideration.
That is, use cases capture who (actors) does what (interactions) with the system, for
what purpose
(goal). A complete set of use cases specifies all the different ways to use the system,
and thus defines all
behavior required of the system--without dealing with the internal structure of the
system.