11 August 2015

Capture Requirements with Use Cases

The Use Case Principle

The main idea behind use cases for requirements capture is that all useful system functions have an impact at the interface between the system and the outside world. If no one will ever notice whether a function is present or missing, there's no need to implement it.

Every component, every circuit, every line of code must be able to justify its existence by serving some aspect of at least one interaction with the outside world; that is, it must help to realize a use case.

A use case model treats the system as a "black box"; it's completely described by its externally evident behaviour. Whether the product is a rail line or a spreadsheet, a clear understanding of the use cases tells you what needs to be achieved.

Why not a Functional Spec?

A functional specification lists the functions to be included in the product. You can't be confident that every product with those functions will be the product the client expects. Very often it isn't; every project manager has a story about a product that "met the spec" but failed to satisfy the client. It's easy to blame the users for this, to say that they don't know what they want but, pace Dilbert, the fault is in the approach.

Use cases are specific to the client's view of the requirement; a complete set of use cases clearly identifies what the client wants the product to achieve to be acceptable. A pickup truck and a car with a trailer have the same functionality. Rather than counting axles, the best way to choose between them is to examine the intended uses. That's where use cases come in.

Problem: Functional specifications in disguise

Functional specifications and the techniques for producing them are hard-coded into the viscera of many analysts. The result is sometimes a cargo-cult approach to use case definition; use case templates and terminology are used to write what is actually a functional specification. The main symptoms of this approach are business work flows with use case names, internal actors, and extensive 'non-functional requirements' with functional effects.

Every Use Case has an Actor

Since the only relevant functions are those with with an external effect, someone or something, an Actor, is out there to interact with the system implementing the function. The actor’s presence at the interface is motivated by some goal to get value out of the system. Successfully enacting a use case will achieve the actor's goal.

A use case without an actor—one that just describes system activity—is a useless case because it doesn't address any requirement, and it preempts design. It is most likely a disguised functional spec. It's also a strong indicator that there's a real use case missing: the use case in which an actor sees the results of the proposed system activity.

Identifying a Use Case

One of the reasons we enlist use cases for requirements is that well-chosen use cases can efficiently drive and organise all the important parts of the product design and development process.

From this point of view, the most important characteristic of a use case is that it's atomic; that is, it provides a complete and distinct service to the actor. There should be no value to the actor in enacting only part of a use case, and enacting a single use case is sufficient to get a desired value from the system. The imagined scenario is: an actor walks up to the system, enacts one whole use case, and walks away smiling. There's a variant of this involving an actor that's another system. In that case, delete the smile.

If you find a useful interaction that involves only part of a use case, the use case is too big - split it up. If you find two use cases that are inseparable, they're too small - join them by defining the use case that glues them together.

Use cases are not the only input to product definition. In addition to use cases, there are a variety of analysis and design models that contribute to the communication between the users and the designers. Increments of the product itself provide for continuing the conversation throughout the elaboration and construction phases. When you're identifying use cases, it's important to keep in mind that use cases are not the users' only kick at the can, just their first kick at the can.

Project Management with Use Cases

If your use cases are atomic, then each can be treated as a unit that drives everything from design to test and help. Because they're atomic, they can be counted - no more "percent complete"; it's either done or it's not.

A good use case is a unit of development

Given that the system's users have no interest in partial use cases, there is no value in partial use case development. This is particularly relevant when the project is taking an incremental approach. Each increment has to show new capabilities, and that means one or more whole use cases.

A good use case is a unit of test

If development will proceed in increments of whole use cases, it makes a great deal of sense for testing to proceed in sync. The atomicity of use cases makes it convenient to develop independent test scenarios for each use case, greatly simplifying the test plan.

A good use case is a unit of help

The best help systems and user manuals are written with a goal-oriented organization; that is, 'to accomplish this, do that'—the short definition of a use case. Writing a contextual help unit and a user manual section for each use case ensures both completeness and relevance.

Competent user interface design presents the user with choices for only those things the user is permitted to do. To enact a use case, the actor will need all the relevant access permissions. The system should not let the user start a use case they lack the permissions to complete.

Preconditions

A precondition is part of the description of a use case. It must be met before the use case starts or the use case will fail. In general, if a precondition is not met, it shouldn't be possible for the actor to start the use case. When this can't be known in advance, and the precondition is not met, the use case must fail; if there's a means of recovery, it's not a precondition, it's an alternate path.

Post-conditions

A post-condition is a statement that the system guarantees will be true if the use case is successfully enacted.

Post-conditions for one use case are always pre-conditions for some other; otherwise, no one would ever know whether the post-condition has been satisfied. In general, post-conditions are used as reminders to the designers and as indicators of dependencies between use cases. Little is lost if they're omitted entirely.

Invariants

An invariant is a statement that must be true throughout the process of enacting a use case. It acts as a constraint on the realization of the use case. If they are sufficiently interesting, and prescribe use case behaviour, invariants can often be expressed as associated use cases.

The Bottom Line

In an organisation that does successful projects, requirements aren't given or discovered; they're negotiated. To ensure that the right line is drawn between the desirable and the practical, an on-going dialogue between the designers, the analysts and the users is vital. Good use cases, validated with good design artefacts, record the agreement between these stakeholders in clear and concise language.