Good Practices

Use cases are a really simple technique, which is why most beginners do not pay enough attention to them and refuse to spend much time learning them properly. In this and the subsequent chapters, we would like to present various dos and don'ts that may not be obvious at first glance but which could significantly impact the quality of your use case specifications.

Tips for Use Case Components

From the reader's perspective, it must be immediately clear what the scope of the analyzed system is and who the beneficiary of the particular use cases is. The tools the use case technique provides for this purpose are the system boundary and actors:

aa

System boundary

The system boundary represents the system in which the use cases will be realized. The scope of the system is indicated by the use cases that are within the boundary. When using the use case diagram, always include the boundary to make it clear which system will realize the use cases. This way, the diagram can be presented without any extra context, and the reader will still be able to understand it.

Actor

Regarding actors, these rules should be followed:

  1. Name actors with singular, business-relevant nouns
  2. Actors model roles, not positions or real persons
  3. Actors do not interact with each other
  4. The actor's name is not sufficient. The actor should be supplemented with a short description to provide the basic characteristics of the user class

System and Time

Sometimes there is a need to describe a system function that is not triggered by a user but rather by an external event. The common practice is to use a System or Time actor. For example, the use case "Delete all inactive customers" in the following picture will be triggered automatically every 6 hours, or it could be triggered by an external system.

aa

From a UML perspective, there is nothing wrong with the picture, and people will understand what you mean. But when using a system or time actor, it is likely that the modeled use case is not at the user-goal level. In most cases, use cases triggered by another system or by time are secondary use cases, or they are just administrative functions which do not provide the expected value to the user. Therefore, if you decide to use a system or time actor, think twice about whether it is really a use case that should be included in the overview of the system's user goals. Sometimes it might be, but mostly it will not.

EXAMPLE

UC Delete All Inactive Customers

  1. System goes through all customers not marked as inactive
  2. If the customer hasn't ordered an item in the last 12 months
    • System marks the customer as inactive
    • System sends an email to the customer with a promotional code
  3. Otherwise, the system proceeds to the next customer
  4. Use case ends

The above use case is a typical representative of a "technical use case" – there is no user-system ping pong. This often tempts analysts to start describing implementation details, which should not be part of the use case – for example, "System marks the customer as inactive". For this reason, we always advise modeling this kind of use case as a secondary use case. This way, it will appear on the list of user goals but will include just a short description of what the goal is that the user expects. The rest of the necessary information will be described in a separate activity.

Tips for Writing Effective Use Cases

Learning to write a use case scenario is quite easy, so analysts adopt it very quickly. However, learning to write consistent use cases, which are all at the user-goal level and which meet all requirements of a good use case, is much harder. Mastering it requires training and experience, and the more use cases an analyst writes, the better the use cases will be. Here we are presenting some tips to help you write better use cases from day 1.

Simple Scenario

The first tip for writing use case scenarios is to avoid alternate and exception flows unless they are really necessary. This is quite contradictory to what most materials teaching use cases advise, but there is a reason for it. The goal of alternate and exception flows is to separate the main happy path scenario, which is the most likely, from the alternate side flows. They make it possible to keep the main scenario clean and unpolluted by IFs and ELSEs, as it is not a good idea to create branches in textual scenarios. However, use cases are popular for their simplicity, which enables anybody, including business stakeholders, to learn the main user goals. Branching, including, extending, or even inheriting effectively kills this benefit. So always first evaluate whether advanced use case techniques are always the best choice. Maybe including an IF in the scenario or separating the flows into two use cases will make the specification easier to read.

To provide the greatest value, use case scenarios should be kept as concise as possible. Apart from avoiding implementation details, use case scenarios should include only 5 to 9 steps. If a use case is shorter than 5 steps, it probably will not provide the expected value. What is more, the specification will probably contain dozens of these small use cases and will become hard to manage. Similarly, a use case with more than 9 steps is very likely to be overcomplicated; it probably contains unnecessary details or is a combination of two different user goals.

Use Case Name

Naming use cases properly may seem like an insignificant aspect, yet the quality of the use case analysis relies on it heavily. Use cases named "Issued invoice" or "Yearly report" do not clearly state the goals they are expected to deliver, and readers can only guess what is behind them. Without verbs, it is impossible to tell what the user goals are. On the other hand, Book a ticket expresses clearly what the result of the use case is.

The common pattern is to name use cases as an active goal phrase: <verb> <direct object>. This gives us use cases such as Book ticket, Issue invoice, or Open account. It clearly states what the user expects from the system, and it has a unified form across projects.

Terminate the Flow

It is a good practice to end the use case scenario with a statement like "The use case ends" or something similar. Including this at the end of each scenario doesn't make readers guess whether it really ends here or whether the use case is still under development.

Replace Actor With "User"

Although different use cases might be performed by different actors, do not include the actor name in each scenario step. Instead, use just "User does something". In all cases, the user is the actor, and this way, you will not have to change the scenario if the actor changes.

Do not tune them to perfection

Writing use cases is more art than science. Since they are written in natural language, they carry all the traps associated with it. When you write use cases, you should follow all the advice presented in this chapter, but you should not tune them over and over again. As with any other text written in natural language, it will never be perfect. So deal with the fact that even an imperfect use case is acceptable as long as it clearly presents the user goal and is understandable to all stakeholders.

Use Case Packages

Big enterprise systems might consist of dozens of use cases, and storing them all in a flat structure is not the best strategy. It is a good practice to put related use cases together into separate packages. For example, use cases related to invoices would be placed in the "Invoice management" package, while use cases dealing with customers would go into the "Customers" package. Just as we recommended limiting the number of scenario steps to 9, the same rule applies to the number of use cases in each package. Hence, the packages remain narrow, and all use cases from a package will fit into a single use case diagram.

No Extend, Include, Inheritance

Including, extending, and inheriting use cases are standard use case features defined by UML. The include relationship is used to inject a flow into another use flow. The extend relationship does the same, but only if some condition defined by an extension point is met. And inheritance allows creating a base use case which might be inherited and extended by its child use cases. Examples of the include and extend relationships are depicted in the pictures below:

aa

aa

When analysts start learning use cases, including and extending look very tempting because they promise to save the analyst's time through reuse. Unfortunately, they very often do more harm than good. First, using these relationships very often causes analysts to start thinking about use cases as functions. This often leads to analysts performing a functional decomposition. For example, Find Order from the example above is not really a use case and should not be modeled like this at all. Second, using these relationships makes use cases less readable and hard to follow for business stakeholders.

Use Cases and Post-Release Documentation

Use cases as a technique for identifying basic user goals are very useful in the early stages of a project, when an analyst needs to define the scope of the system and understand what the stakeholders expect from it. Once the system is implemented and released, use cases as a requirements analysis technique are no longer important. From the post-release documentation's point of view, it is more important to capture what happens when a particular button is clicked or what service is called when the list of items is refreshed, rather than focusing on abstract, technology-independent steps. However, even for a released system, it is important to have a high-level overview outlining the basic user goals of the system. Therefore, some of the use cases might be beneficial even in the post-release phase, as they may be used to provide an overview of the system.