A use case describes an example interaction between two or more parties, in which one of them seeks to achieve a goal. Usually the active party is a human user, and the responding party is a computer system. The main body of the use case consists of about 3-9 steps, in each of which one party requests an action from another, or responds to a request from another. There are a variety of conventions, stemming from experience of what has been useful in practice, specifying in more detail what use cases should describe, and how they should describe it. This web page summarises some of the many ways in which use cases are useful. Any methodology risks becoming a meaningless ritual over time. I hope that we can prevent this happening to use case driven methodologies if we keep in mind the purposes of use cases as we read and write them.
Here follows a "use case for use cases." It is not representative of most use cases, because it is not a use case showing how a user interacts with a computer system to achieve a goal, but a use case showing how use cases co-ordinate the activities of many people as they proceed through one iteration of a development process. It also has more steps than usual. Nevertheless, it is a sequence of steps, where each step is a statement in the active voice describing a named actor performing the step. On re-reading Alistair Cockburn's excellent "Writing Effective Use Cases." I find that use cases are not the only useful tool presented there for describing the uses of use cases. I have also taken advantage of summary formats described in that book, appending notes to them as seemed best to me. Where not otherwise specified, references are to sections in that book - e.g. 17.3 is to section 3 of chapter 17, P174 in my copy.
This is intended as a high level use case, to show how one iteration of an iterative development process might use use cases. Like most high level use cases, it can be used to motivate the lower level use cases, and to illustrate how one lower level use case leads on from another. In some cases this might show that the GUI needs to put controls used for use cases A and B close together, as B always follows A. In this case we can see that once the use cases have been written, a number of different tasks can be performed almost in parallel, with few dependencies between them.
We have documented where all that time went, and have preserved enough further information that if we repeated the exercise we would not be starting from scratch.
Use cases provide all and only black-box behavioural requirements that the design must meet. (17.3). Here is a Scope Table (Figure 3.1) showing what is in and out of their scope.
| Topic | In/Out |
|---|---|
| Interactions | in |
| Behaviour | in |
| Technology Requirements | out |
| Development Process | out |
| Security (and Safety) | out |
| Usability | out |
| Performance (and Scalability) | out |
| Legalities | out |
| Numbers | out |
| Data Modelling | out |
| GUI Details | out |
By a technology requirement, I mean, for example, "This software must actually work on Windows Vista." Similarly, a development process requirement might say "This project must be managed using the Prince II small project proceedures." Statements such as this are perfectly clear as they stand; there is not need to make use cases out of them.
Some of the procedures used, for instance, to assign privileges to user accounts, may be specified with use cases. However, security, like safety, is also concerned with functions that the system must not provide. It must not be possible, for example, for a user with only monitoring access to control equipment. No single use case can illustrate this convincingly, because the addition of another use case requesting this, or, more likely, the combination of several apparently harmless use cases amounting to this, would contradict this requirement. Security has its own specialised techniques, in which a set of security properties are agreed, and the developers then construct and maintain a security case that proves that the system has these properties. A similar argument follows for safety. Indeed, in technical terms we can say that the security case is concerned with proving safety properties, whereas use cases are concerned with stating liveness properties.
Use cases are an important input when creating a usable system, but typical usability targets are the time to become familiar with the system, the speed at which users can get things done with the system, the error rate seen while they use the system, the period over which users will retain their knowledge of the system, and the satisfaction (or otherwise!) with which users leave the system. These targets do not map to any single use case.
Performance is not easily dealt with by any single use case, or even by annotating any single use case to add timing information, because it is influenced by features of the system as a while, such as the total load on the system produced by the demands of other users, the total size of the data contained within the system, and so on.
Data Modelling is an important part of the system design, which has its own very effective notation, complete with a proper mathematical theory. There is nothing to be gained by trying to shoe-horn this into use cases. A data model should be produced, but it is out of scope here.
Use cases should describe the interactions with the system, but at a level no lower than "The user requests a small black coffee." Stating that the user achieves this by selecting a radio button makes the use case too complicated. It is far better to leave the decision at "the user requests" for now, and settle on exactly how they request it later, perhaps in the presence of users and with a paper prototype and a plentiful supply of blank paper to hand.
Here is an actor-goal list (section 3.1), showing who makes use of use cases, and why. Normally, you would also have a third column, showing the development priority: I omit this because different projects will put different priorities on different goals.
| Actor | Goal |
|---|---|
| Implementor | Brainstorm failure cases |
| Implementor | General systems documentation |
| Implementor | Negotiate requirements |
| Implementor | Predict future requirements |
| Manager | Estimate and track work remaining |
| Passive Stakeholder | Validate requirements |
| Technical Writer | Rough out "how to" documentation |
| Tester | Formulate test procedures |
| Usability expert | Learn user tasks and their relationships |
| User | Agree requirements |
An actor name reflects the role that a person has assumed at any one time, and not a permanent assignment of people to posts. This is one reason why "Implementor" dominates this table. When use cases are used to communicate information between two people, we will very often label the one with more information on the implementation of the system the implementor, even if they do not routinely build things. In practice, the "Implementor" discussing the scope of the system with users or user representatives may be the same person, who, as "Manager" tries to get the programmers to assign at least relative units of work to use cases when they are trying to work out how long all of this is going to take.
The second reason why "Implementor" dominates this table is that I believe that, although "Writing Effective Use Cases" largely describes use cases in situations when the interaction being described is between the system under design and an external actor (such as a human user), use cases are also the single best way to describe the internal implementation of a system. In these cases, the system under design - for the purposes of an internal use case - may only be a small part of the system being delivered to the customer, and its external actors may be other small parts of the main system. These use cases will be read and written by system implementors, not customers. They are a more informal version of the use cases that would be written if the system implementors sub-contracted parts of the system construction, thus becoming users themselves.
I am not alone in believing that use cases are valuable in API design; in "Practical API Design," Jaroslav Tulach states (Chapter 5) that "A valid use case is the justification for a class or a method in an API." In the Jave One keynote presentation "How to Design a Good API and Why it Matters," Joshua Block states that the true requirements should take the form of Use Cases.
This covers lower, implementation-level, use cases. "Writing Effective Use Cases" also mentions that use cases can be used to document the next higher level, business processes, although these use cases might not match the normal interaction-level use cases as neatly as the interaction level use cases may match the implementation level use cases.
A use case describes routes to two possible destinations, failure and success. The success case may be reached directly, when every single step succeeds immediately, or it may be reached after recovering from the failure of one or more steps. If we consider each step in the use case one by one, we can ask the questions "Can this step fail?" and "If it does fail, what should we do about it?" Such a systematic examination of possible failures can pick out possible failures that would not otherwise be considered until they actually happened in practice. This gives implementors the chance to ask users and other experts for advice on how to handle them. The use case may contain a minimal guarantee: even in the case of failure, the system will undertake to satisfy this guarantee. This might be, for instance, to log the fact that a failure has occured for future investigation, or perhaps to preserve crucial parts of the system undamaged by the failure and return an error indication warning of the problem.
The system should, of course, support its use cases, so the implementors and users can agree a large part of the system requirements by agreeing on the use cases. I have observed that our end users can both read and write textual use cases, that they understand those they read, and that those they write make sense. This is not to be taken for granted; I have seen other users fail to understand more sophisticated notations. Curiously, they don't always admit this immediately. Instead, they may sign off on the requirements, or not, according to whether they trust the implementors at the time. At the start of the project everything gets agreed promptly, and life is good. Unfortunately, however, you are not really getting the agreement you think you are getting, and you are not learning anything from the users, either. Reality may not intrude until you start agreeing the acceptance tests, which will function as use cases if nothing else does. At this point the users realise that the system about to be delivered doesn't match the system in their heads, and they also stop trusting the implementors who are about to present them with it. The implementors, of course, are finding out that all the work they put in building the system has been expended in building something nobody really wants. If you are involved in a project that does not agree textual use cases with the customer, I suggest that you get a few of the most important acceptance tests discussed very early, just in case.
When providing any form of documentation to anybody, you should consider just how much documentation they are prepared to read. If you provide more than this, the best possible future is that they read the first N pages; you can at least prepare for this by structuring the document as a series of successively longer summaries. Perhaps they will select a few use cases at random and glance through those, in which case they may miss critical features of your solution. Perhaps they will be so daunted by the size of your document that they put it down in a corner, to look at it when they can find time to do it justice, and perhaps they will never get round to reading it at all.
In sections 5.1 and 5.5, and the "Short, True Story," Cockburn points out that you can summarise use cases by moving up a level, asking the question "why?" (to move down a level, ask "how?"). He also gives an example showing that six use cases that people actually read were more effective than hundreds of pages that nobody read.
Note that use cases do not constitute a design; a system should not be constructed as a collection of scripts, each working through a single isolated use case. Hopefully, the designers will be able to come up with a coherent design that supports the use cases without being an exact image of them. This reflects an assumption that the use cases are a series of views of a smaller number of underlying ideas, so that we can provide a more consistent and simpler system by capturing some approximation of the underlying ideas within the design, rather than mimicing each use case in isolation. This is exactly what has been found in designing flight simulators, where the underlying idea is the behaviour of the real aircraft, as dictated by physics or as reported by the results of experiments, and the use cases are the scripts for the lessons that the simulator will have to support. See section 14.2 of "Software Architecture in Practice," by Bass, Clements, and Kazman. In most cases, our underlying idea will be some sort of data model, whether that provides positions and velocities, timestamped sensor readings, or current account balances and histories of transactions. At the other extreme, if you produced the use cases by generating them from a sequence of random numbers, I would not expect to summarise the required behaviour in any more concise form.
Use cases provide lists of stakeholders, who have goals they wish the system to achieve, and interests they wish the system to defend. If you can find a use case where some stakeholder's goal is not met, or some stakeholder's interest is not protected, then you can expect a new requirement to surface when that stakeholder finds out about this. You should consider failure cases as well as success cases.
You estimate the work required to build a system by breaking the job into component tasks, and then matching each component part with a similar task which has been completed, so that you know how long it took. A manager is likely to be involved in many projects at the same time, whereas an implementor is only likely to see one or two at once. This actually provides some justification for manager's habit of imposing work estimates on implementors: since managers see more projects, and see the records of progress in many more projects, they should have more experience to draw on than implementors when trying to recall the time taken to complete similar tasks.
Failing this (or as well as this) break the work to be done into units, and look for classes of similar units. Then, as the first tasks are completed, you will have a better idea of how long similar remaining tasks will take. Rather than picking out individual tasks, you could measure progress according to the number of days you expected to take to complete what you have done so far, and compare this with the number of days actually expended. The Burn-Down chart described in chapter 2 of "Lean Software Development," by Poppendieck and Poppendieck, is similar.
By a passive stake holder, I mean somebody who has an interest in the system and power over it, but who does not use it themselves. Such a person may be a regulatory authority, a trade union group, a consumer watchdog, or a powerful customer. Such a body, if directly involved, can read the use cases to check that the system safeguards their interests. Even if they do not have sight of the use cases, somebody - perhaps even a company lawyer - may wish to use the use cases to check that the system will not break existing agreements, such as the Data Protection Act. Implementors can anticipate changes in requirements when the interests of a powerful passive stakeholder have not been taken into account.
"How-To" documentation can be generated from the use cases, and the use cases should be chosen to cover most of the things that ordinary users will need to do with the system. Most users will read "how to" documentation for particular tasks long before they ever read reference documentation that describes everything that they can expect of the system. Ideally, both sorts of documentation should be provided. "How-To" documention is obviously helpful to the users of the system. It is also helpful to the builders, and especially to the maintainers; by influencing the users to perform particular tasks in particular ways, it makes it less likely that they will wander off into uncharted territory, asking the system to do things that were not anticipated by its designers and have not been tested. Even if the system works perfectly, it is better if everyday use is stereotyped and restricted, because this makes it easier to provide a future revision of the system, which may have slightly different behaviour, without annoying too many users; changes in parts of the system that nobody actually uses will not annoy anybody. If the system encounters every possible request in actual use, then any replacement, or purported improvement, will change the response to at least one required request, and so annoy some current user. Many proposals to increase backwards compatibility, such as making classes final, amount to barriers that restrict the ways in which a component can be used to the minimum set required to satisfy its use cases.
Use cases should translate almost directly into test scripts and test procedures. It should be possible to agree these with the customer as acceptance tests. Because these tests can be available from the very start of design, they can be used as automatic tests from development on. Having multiple generations of tests discourages automatic testing; you build up an accumulation of old tests that continually consume testing time until they start failing, at which point it is difficult to tell what they were trying to test, and whether the failure matters. An early source of tests that can be traced to requirements - or to "how to" guides - will help a lot.
Many approaches to design for usability, such as that in Contantine and Lockwood's "Software For Use" emphasise understanding the basic tasks that the users will want the system to perform, and the relationships between the tasks. They try to design a system that makes it easy for the users to see what has to be done at each step of a task, to see how to do it, and to see that it has in fact been done correctly when they have done it. This typically means building the user interface with particular tasks in mind. You might, for instance group together controls that are used in the same tasks, and place together groups of controls that are used in related tasks. The essential input to such methodologies is the list of tasks, and background information. The background information can be provided by using multiple levels of use cases to group the tasks. A higher level use case is a series of steps, each (or most) of which are instructions to run lower level use cases.
Any use case can have a minimal guarantee, which it will fulfil even if everything that can fail, will fail. Typically this is that, if an error occurs, something is logged so that implementors can debug the problem, and users can try and make things right manually. What would the minimal guarantee be for the use case of writing a use case? I think it would be some kind of forward progress; that enough information has been gained, and hopefully preserved as a writeup, so that anybody asked to do the same thing again wouldn't be starting from scratch. Such a person might not be able to produce a satisfactory use case, but at least they will find that out quicker than the first person to come along. I talked to somebody who had worked on a number of study contracts, and cynically asked him if these writeups ever stated that any further money spent studying the proposal in question would be wasted. It turned out that we reported this just once; the problem was not that the technology had not been developed, or even that it did not do all that it claimed to do. The problem was that nobody could be found who cared whether the technology performed as advertised or not. A writeup to this effect could still be generated, and would save future investigators from fruitless searches.