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 evident at first sight 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 is the scope of the analyzed system and who is the beneficiary of the particular use cases. The tools the technique of use cases has 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. Then the diagram could be presented without any 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 basic characteristics of the user class

System and Time

Sometimes there is a need to describe a system function that is not triggered by the user but rather by some 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 the UML perspective, it is nothing wrong about the picture, and people will understand what you mean. But when using the system or time actor, likely, the modeled use case is not at the user-goal level. In most cases, use cases triggered by another system or 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 the system or time actor, think twice if it is really the 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 the user goals but will include just a short description of what is the goal 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 the analyst will write, 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. It is quite contradictory to what most materials teaching use cases advise, but it has a reason. The goal of the alternate and exception flows is to separate the main happy scenario, which is the most likely, from the alternate side flows. They make it possible to keep the main scenario clean, unpolluted with 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 kill this benefit. So always first evaluate whether the 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, 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 the user goals. On the other hand, Book a ticket express clearly what is the result of the use case.

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 like this. Including this at the end of each scenario does not 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 of 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 for 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 presents clearly the user goal and is understandable to all stakeholders.

Use Case Packages

Big enterprise systems might consist of dozens of use cases, and it is not the best strategy to store them all in a flat structure. 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 to the "Customers" package. As we recommended to limit 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 the package will fit into a single use case diagram.

No Extend, Include, Inheritance

Including, extending, and inheriting use cases are a standard use case features defined by UML. The include relationship is used to inject a flow in 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 it promises to save the analyst's time by reusing. Unfortunately, they very often do more harm than good. First, using these relationships very often causes that analysts start to think about use cases as functions. This often leads to analysts doing a functional decomposition. For example, the 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 the basic user goals are very useful in the early stages of the project when 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 what are the abstract technology-independent steps. However, even for the 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 for providing an overview of the system.