A use case is a description of a sequence of interactions between a user and a system that leads to some goal being achieved for that user.

For example, imagine a thirsty person wants to buy a can of coke from a coke machine. The goal in this case would be the thirsty person obtaining their can of coke. A simple use case description for this might be:

"The thirsty person selects his/her chosen beverage from the list of beverages available in the machine. The system responds by showing the amount of cash that should be inserted. The thirsty person inserts a sequence of coins that add up to the specified amount. The system drops a can of coke into the dispensing tray. The machine updates its inventory and cash ledger."

Use cases are intended to be black box descriptions of system behaviour. By this we mean that the text should describe inputs and responses observable from outside the system. It should not include internal implementation behaviour. Occasionally it is useful to record internal information changes, if they will be observable as part of other use cases, but this should not be implementation detail. For example, in our description above, we mentioned that the machine updated its inventory and cash ledger. There will be other use cases that allow external users to review stock levels, or to do cash balancing when emptying/restocking the machine. Note though that the use case did not describe how this happens.

Use cases need external entities that have a goal the system can deliver. These external entities are known as actors. Actors might be human beings interacting with the system via some kind of user interface. They might be other systems or equipment interfaced to the system being modelled via some kind of networked or electronic connection. They might be external entities that trigger electro-mechanical equipment, such as trains passing over track sensors on a railway signalling system, or a timer in an elevator control system that shuts the elevator doors. In any event, these external entities are considered (a) outside the system being designed, and (b) to have a will of their own (the system cannot predict when or what input they might give to the system at any moment in time).

Use cases form the main part of functional requirements documents. As such, it is important that they are written using terminology familiar to the stakeholders from whom the requirements are elicited. This is necessary so that requirements analysts or agile product owners can take the use case descriptions back to the stakeholders and do walk-throughs with them to confirm the requirements are complete, unambiguous, and sufficient.

Why should use cases be considered a good format for gathering and documenting functional requirements?

There are a number of reasons actually. No single reason makes them better than all other approaches to capturing functional requirements, but collectively these reasons make a strong case.

First, a use case captures the sequential behaviour that yields a goal. This is a natural way to describe something, more natural than describing its structure or its non-functional characteristics. For example, if I were trying to efficiently describe what an elevator is, I wouldn't begin by saying 'It has a door on each floor, plus two buttons usually placed one above the other.' I'm more likely to say that it is a device that can carry people between the floors of a building. Behavioural descriptions are richer sources of requirements that people in the problem domain can more easily relate to.

Second, a use case documents sequences of interactions. Other more traditional functional requirements formats can bury this sequential aspect, or make it appear of second level importance. For example, a common strategy for documenting requirements, functional or non-functional, was to form numbered lists of requirements statements based on words like 'must', 'shall', 'may' etc. Sequential behaviour was often inferred from the numbering scheme for these single statements of requirement, but the emphasis was on the fact that each numbered statement was a separate single requirement. With a use case, the structure of the requirement is based around goal-driven sequences of interactions, these being natural ways to learn about or describe a subsystem. In this format, it makes very rich behavioural data available to the developers, in a format that they can easily use to construct the code that realises that behaviour.

Third, a use case is by its very nature already nine tenths of the way to becoming user documentation. If I wanted to know how to use a system, I'd like to be told what to input and what to expect to observe as an output.

Fourth, a use case describes the expected sequence of interactions that yield the goal, plus intermediate observable outputs. It also describes the alternative sequences that branch off the primary sequence when unexpected events or conditions occur part way through the use case. This combination of paths through the use case describe behaviour in a format that lends itself readily for translation into test scenarios. Hence use cases are most of the way toward describing functional requirements in terms of the tests that will be used to confirm those requirements were met.

Because of these reasons, use cases have become one of the most widely used formats for capturing and recording external descriptions of system behaviour prior to system design and construction.