CRUD Pattern in Use Cases

If you have ever been writing use cases for a data-oriented system (i.e. CMS), you have probably noticed that there is a problem with the large number of use cases like "Add an article", "Remove an article" etc. If you have all CRUD operations available for all objects in the system, you can finish with up to 4 x number-of-objects of use cases. You can reduce this number by introducing the CRUD pattern, which I would like to present you in this blog entry.

Introduction

If you have ever been writing use cases for a data-oriented system (i.e. CMS), you have probably noticed that there is a problem with large number of use cases like "Add an article", "Remove an article" etc. This kind of operations are typically called CRUD operations (C-reate, R-etrieve, U-pdate, D-elete.)

If you have all CRUD operations available for all the objects in the system, and you would like to provide a complete set of use cases for all of them, you will probably finish with up to 4 times the number of objects of this kind of use cases. The question is could we reduce that number?

CRUD Pattern

The solution to this problem might be a so-called CRUD pattern [1]. Its idea is quite simple. Instead of introducing a separate use case for each CRUD operation, you create a single use case "CRUD object_name", and present all operations as separate flows. This is somehow contradict to the idea of use cases, which should represent a goal important for an actor, and in that case it would be difficult to call CRUD a single goal. Sometimes people use also names like "Manage object_name." All in all is about the same idea. You can see some examples of CRUD use cases presented in Figure 1.

Fig. 1. An example of simple CRUD use cases presented on Use Case Diagram

Partial CRUD

Sometimes it is justified to exclude some of the CRUD operations from a single CRUD use case to a separate one, because they are more complex. For instance, imagine the system were you can create, store, and present articles. Imagine that operations R,U,D are all simple, but the Create operation is definately more complex. For instance, it involves not only the Author of the article to participate, but also a Reviewer, who has to accept the article (or reject it for revision etc.) In that case you can consider creating "RUD article" and "Create an article" use cases.

Textual Representation of CRUD Use Cases

The question is how to present CRUD use cases? Övergaard and Palmkvist [1] suggested to introduce a separate main flow for each kind of "sub-goal" - CRUD. This is a good approach, but some use-case editors are not able to do so. In that case you can consider placing one of the operations as a main flow and other as extending flows. A simple example of both approaches is presented in Figure 2.

Fig. 2. An example of two approaches to present CRUD use cases

Going Further - Introducing Variants

By introducing CRUD pattern, you can reduce the number of use cases up to 4 times. You can also have many objects, for which CRUD operations look completely the same. In that case you can introduce variants. For example, if you have two objects like article and blog entry in your CMS, and their management is exactly the same, you can create one use case called "CRUD <CMS object>." Then, in your domain-objects model (or in glossary), you can describe that both article and blog entry are examples of CMS objects. Of course as usual you have to keep balance between the "compression" of your model, and its maintainability, and understandability.

There's only one really minor issue left: the main scenario assumes starting from a list of articles presented to the actor. The pattern is useful in shortcutting long winding discussions regardless of this small issue. I'll use it in my classes!

We have created a LyX layout that supports Requirements, Features, Use Cases and Test Cases. It also supports tractability via references. You can find it on GitHub at https://github.com/practiceprovider/srs