One of the most common questions students and inexperienced practitioners ask when creating a use case model is how to write CRUD (create, read, update and delete) use cases. There are several options to represent these functions:
- Not representing it as a use case (Bittner; Spence, 2002; Lily, 2000)
- Create one “manage” use case.
- Create, update, and delete functions are represented as alternative flows (Cockburn, 2000)
- The use case has several basic flows (Övergaard; Palmkvist, 2004)
- Create each use case separately.
- Use the extends relationship from a “read” use case.
- The create, update, and delete use case has a includes relationship with a “read” use case.
- Use a precondition to specify specific CRUD use cases from a base use case (Cockburn, 2000)
- Represent the use cases without any relationships.
Even though this is a common issue, there is no correct answer for this question. It is a matter of preference. In fact, this is one of the main problems of the use case technique: there is no single method. Each author proposes different terminology, concepts, semantics, templates, rules, and guidance on how to create them (another post presents the result of a survey on use case concepts).
Before presenting these options, it is important to discuss in what situation they apply. This discussion is not for every set of create, read, update, and delete functions. Schneider and Winters (2001) present an interesting example of this issue. In an order processing system it would be possible to say that “Place order” is a create function; “Get Status from Order” is a read function; “Return Product” is an update function; and “Cancel Order” is a delete function. However, as these use cases are the main part of the system, it would not be reasonable to omit them or even define them in a single use case. Some may say they aren’t exactly CRUD use cases; others will say they are very important CRUD use cases (and so the rule does not apply to them). In any case, we will discuss simple create, read, update, and delete functions.
Some authors propose that CRUD use cases should not be represented. Bittner and Spence (2002) argue that CRUD use cases are not helpful – and tedious to write. There is no behavioral significant flow of events: it is just enter data, validate, and commit (Bittner; Spence, 2002). Consequently, there is little risk of misunderstandings. The most important part of the CRUD behavior is the data validation, which can be captured by domain models along with the data validation rules. Lily (2000), on the other hand, argues that CRUD use cases are inadequate. They are an attempt to make requirements object-oriented, as they are related to a group of actors who share an object – instead of being directly related to actor goals. As a result, CRUD use cases have several problems: they are related to several actors; the specification is typically long; and the relationship of the use case to the actors is suspect.
On the side for CRUD use cases, Övergaard and Palmkvist (2004) argue that they must be represented because someone will be using the system to provide information, and, consequently, if they are not represented, the use case model will not be complete. However, as defended by Kulak and Guiney (2001), their priority should be low.
The authors who propose creating CRUD use cases (Cockburn, 2000; Övergaard; Palmkvist, 2004; Schneider; Winters, 2001) do not agree in the format that should be used. However, there is an agreement that in some situations it is more adequate to represent them as separate use cases or as a single use case. As a create, read, update, or delete function grows in size, importance, and/or complexity, it makes more sense to represent it in a separated use case (Cockburn, 2000; Övergaard; Palmkvist, 2004; Schneider; Winters, 2001). A separate use case helps dealing with the function complexity (especially if there are several alternative flows), makes it easier to read, and allows representing different security levels (Cockburn, 2001). On the other hand, if the CRUD functions are very small and trivial, it may be more adequate to represent them as a single use case. The main benefit of a “manage” use case is to simplify the use case model (Cockburn, 2001). Since every use case must be “labeled, tracked, scheduled, tested, and maintained” (Cockburn; 2001, p.110), a single use case is economically more interesting. Furthermore, creating a single use case ensures that all four functions are considered and makes them more valuable to the stakeholders (Övergaard; Palmkvist, 2004). Cockburn (2000) suggests that the requirements engineer should start with one use case and then break it in other use cases if necessary; Schneider and Winters (2001) suggests the opposite – the functions should be created as a separate use cases and then merged if necessary –; and Övergaard and Palmkvist (2004) don’t suggest an order, but recommend creating a separate use case if the requirements engineer is not sure what is the best organization.
Regarding the exact format to represent the CRUD functions, I’ve presented in the beginning of this post several options that I’ve seen (there is also another one proposed by Merrick and Barrow (2005), but it is not UML compliant). The choice is yours – in fact, should be the choice of your template or metamodel. But I personally prefer option 2.A…
References
Bittner, K., Spence, I., 2002. Use Case Modeling. Addison-Wesley.
Cockburn, A., 2000. Writing Effective Use Cases. Addison-Wesley.
Kulak, D.; Guiney, E. 2003. Use Cases: Requirements in Context. 2nd ed., Addison-Wesley.
Lily, S. 2000. How to Avoid Use-Case Pitfalls. Dr. Dobbs.
Övergaard, G.; Palmkvist, K. 2004. Use Cases Patterns and Blueprints. Addison Wesley.
Schneider, G.; Winters, J. P. 2001. Applying Use Cases: A Practical Guide. 2nd ed., Addison-Wesley.