Mark Collins-Cope is Technical Director of Ratio Group Ltd., a consulting and training company specializing in helping organizations migrate effectively to an OO approach to software development. He can be contacted at [email protected].
Use case analysis is a requirements capture technique that is used most often in the early stages of OO and component development projects. It was first introduced by Ivar Jacobson in his book Object Oriented Software Engineering,1 although the description of use case analysis presented in this book has been interpreted, in practice, in many different ways (one consequence is that, seemingly, no two use case analysis projects ever deliver the same information).
When engineers first undertake use case analysis, a number of issues are raised for which easy answers can't be found in the text books, such as:
- What is the appropriate level of granularity for use cases?
- If large-grained use cases are used, should they be decomposed into "lower-level" use cases?
- If so, at what point should this decomposition stop, and how should these sub-use cases be used?
- Should user or external system interface functionality be described in use case text?
- How do dialog descriptions fit in?
- Where do report layouts go?
- Should user interface dynamics be included?
- Should interchange file formats or interface protocols form part of the documentation?
In this article I look at the RSI approach to use case analysis. This approach provides a framework for analyzing and understanding potential use case deliverables and their interrelationships, with the intent to answer the questions detailed above. The RSI approach also aims to assist in maximizing software reuseby partitioning functionality into those aspects that are concerned with "managing the interface" (to an actor) and to those areas that make up the reusable core of the system.
RSI STRUCTURES USE CASES IN THREE TYPES RSI divides use cases into three categories, shown by the UML stereotypes: << requirement>>, <<service>>, and <<interface>>.
Figure 1. The relationship between <<requirement>>, <<service>>, and <<interface>> use cases.
<<requirement>> use cases document business processes for which automated support may be required. They detail the requirements driving the development of a system, but do not define the details of a system's functionality. <<interface>> use cases provide a detailed description of the interfaces presented to the system's actors and association functionality. <<service>> use cases provide a detailed description of the underlying functionality a system offers in a manner independent of the needs of any particular interface. An alternative view of the relationships between the RSI use case types can be seen in Figure 2.
Figure 2. Relationship between RSI use cases.
The separation of <<interface>> and <<service>> use cases can be viewed as a layering of the functionality of a system, with <<interface>> use cases providing a "translation" role between the nuances of a particular interface and the essential core of a system (see Fig. 3).
Figure 3. Separation of the functional concerns of the interface and the core of the system.
<<REQUIREMENT>> USE CASES A <<requirement>> use case defines a business process for which some automated system support may be required (e.g., "sale of goods," "resource a course," "open a new account," etc.). <<requirement>> use cases may be documented in the manner described by Cockburn,2 detailing:
- the actor
- the objective of the use case
- a process-oriented decomposition of the use case into a sequence of steps
- a list of any extensions dealing with deviations and exceptions in the normal sequence of events. (Cockburn's exception-numbering convention is particularly useful in these descriptions.)
- a list of variations (in actor types) to avoid use case scenario explosion
<<INTERFACE>> USE CASES <<interface>> use cases describe functionality that is concerned with managing the interface between the actors of a system and the underlying services it offers. <<interface>> use cases undertake the role of "translating" the information provided by an actor into a form acceptable to a set of underlying <<service>> use cases. To do this, they factor the elements of functionality that are more related to the interface than to the underlying system. <<interface>> use cases may be documented as follows, detailing:
- the objectives of the interface
- a detailed description of any interface formats used. This might include user interface designs (dialogs, etc.), report layouts, file formats, interface protocol descriptions, etc.
- a step-by-step description of the functional aspects of the interface, such as user interface dynamics (e.g., "when the 'select customer' button is clicked, the 'accounts' list-box is refreshed"), file processing, how report contents are made up, etc.
<<SERVICE>> USE CASES <<service>> use cases define the underlying functions offered by a system in a manner independent of any particular interface concerns. <<service>> use cases may be specified as follows, detailing:
- the objectives of the service
- a list of input parameters detailing the information (if any) that is passed to the use case from its calling environment (e.g., customer, account, date, etc.)
- a list of output parameters detailing the information (if any) that is passed from the use case to its calling environment upon termination (e.g., set of overdrawn customers, all new accounts, etc.). Both input and output parameters may be described in terms of objects in an associated specification object model.
- the preconditions of the use case, describing what conditions must be true of the system before the use case can be initiated. Note that precondition descriptions may cross-reference an associated specification object model and could be specified in OCL.
- the postconditions of the use case, describing any changes that will be made to the internal state of the system once the use case has been completed. Note that postcondition descriptions may cross-reference an association specification object model and could be specified in OCL.
Two flavors of <<service>> use cases emerge: (1) <<update service>> use casesthose that change system stateand (2) <<query service>> use casesthose that retrieve information without changing system state.
The input parameters to <<query service>> use cases are typically used to provide selection criteria by which sets of objects within the system will be identified. These are then returned in the output parameters. The input parameters to <<update service>> use cases are typically objects returned by a previous invocation of a <<query service>>. <<update service>> use cases do not usually deal with selection criteria.
RSI USE CASES ARE INTERRELATED <<requirement>> use cases are decomposed into the <<service>> and <<interface>> use cases necessary to implement those parts of the requirement that should be automated. The interrelationships between <<requirement>> and <<interface>>/<<service>> use cases may be shown using an <<extends>> trace on the use case diagram.
<<interface>> use cases invoke (include) <<service>> use cases to gain access to the core elements of the system. The two subdivisions of <<service>> use cases are typically used in the following manner:
- <<query service>> use cases are used by <<interface>> use cases to provide information necessary for the construction of (user) interface dynamics. For example, in a banking system, double-clicking on a particular customer in a "customers" list-box may cause an associated "accounts" list-box to be refreshed with the chosen customer's accounts. To retrieve this information, a <<query service>> would be used ("select accounts by customer" in this case).
- <<update service>> use cases are used by <<interface>> use cases to change the internal system state (to actually "do" something). The parameters of the <<update service>> will have typically been returned by a previous invocation of a <<query service>>. The interrelationships between <<interface>> and <<service>> use cases may be shown using an <<includes>> trace on use case diagrams.
A WORKED EXAMPLE This example looks at the need for automation in the check clearing and interbank transfer aspects of a retail bank.
Figure 4. <<requirement>> use case model for retail banking example.
<<Requirement>> Use Case Model Two <<requirement>> use cases are identified: "processing checks and credits" and "interbank transfers." Figure 4 illustrates the use case model, and it is described as follows:
Use case <<requirement>>: "process checks and credits"
Objective:
To enable clerks to process the paperwork associated with checks and credits, entering the relevant information into the bank's systems.
Steps:
1. Checks and credits are delivered in (paper) batches to the clerk's desk (not automated).
2. The clerk picks the next check or credit, and calls up the relevant bank account information on the system (automated).
3. The clerk enters the check/credit details (automated).
Extensions:
2a. The check or credit is not related to an account on the bank's system.
2a1. The check or credit is put into a "rejects" pile (not automated).
etc.
Use case <<requirement>>: "interbank transfer"
Objective
To enable the reading and writing of files sent via the banking network.
Steps:
1. Interbank transfer files are sent (nightly) over the banking network to a well-defined place in the bank's computer system. Files conform to a defined format (automated, but not part of this system's functionality).
2. At a configurable time, the bank's system reads and processes the credits and debits in the file (automated).
3. These are entered into the bank's system (automated).
Extensions:
1a. The transfer fails.
1a1. This is logged on the external system (not automated in this system).
2a. The file is not there.
2a1. A note is made in the system log. Use case is terminated (automated).
2b. There is a formatting error in the transfer file.
2b1. A log of the offending part of the file is written to the "outgoing error log" file. If possible, the remainder of the incoming transfer file is processed as normal (automated).
3a. The account for which the transaction is specified is not a valid account in the system.
3a1. As per 2b1, detailing the transaction (credit or debit) that failed (automated).
Figure 5. <<requirement>>/<<interface>> use case model for retail banking example.
FROM <<REQUIREMENT>> TO <<INTERFACE>> MODEL The following <<interface>> model meets the automation requirements detailed in the preceding description and in Figure 5. Steps 2 and 3 of <<requirement>> use case "process checks and credits" are refined into the following <<interface>> use case description:
Use case <<interface>>: "enter transaction details"
Objective:
To provide an interface enabling clerks to enter transaction-related details into the system.
Formats:
Functionality:
1. Adding a character into the "Customer Surname" field causes a list of those customers on the system matching the (possibly incomplete) name shown in the field to be displayed in the "Customer" list-box (using <<query service>> "select customer by name").
2. Selecting a customer in the "Customer" list-box causes that customer's accounts to be displayed in the "Accounts" list-box (using <<query service>> "select accounts by customer").
3. Clicking on the "Check" radio button causes the "Check No." field to be enabled.
4. Clicking on the "Credit" radio button causes the "Check No." field to be disabled.
5. Clicking "OK" causes the following dialog validation to take place: Account selected, Value entered, Check number entered (if "Check" radio button selected).
6. On completion of validation, the details provided are entered into the system (using the <<update service>> add transaction).
Steps 2 and 3 of the <<requirement>> use case "interbank transfers" are refined to the following <<interface>> use case:
Use case <<interface>>: "process interbank transfer file"
Formats:
The interbank transfer file is formatted as follows:
<Account No.><Transaction Type> <Value> [<Check no.>]
e.g.
122312 credit 234.55
123345 check 1244.43 019876
etc.
The "outgoing error log" file is formatted as follows:
<error-code> <related text (from input file)>
e.g.
217: input error line 234: '122341 check 3345.3'
etc.
Functionality:
For each line in the interbank transfer file, the corresponding transaction is added to the system (using the <<query service>> "select account by number to validate the account," and the <<update service>> "add transaction enter the transaction").
From <<Interface>> to <<Service>> The full use case model for the retailing banking requirements is illustrated in Figure 6.
Figure 6. Full use case model for retail banking example.
The <<service>> use cases are documented in the following manner:
Use case <<query service>>: "select customer by name" (in:theNameString, out:theCustomers)
In:
theNameStringa (possibly partial) name string that forms the criteria by which customers will be selected
Out:
theCustomersset of customers meeting matching the stated criteria
Objective:
to return a collection of customers whose surnames match the (potentially partial) string theNameString.
Precondition:
True.
Postcondition:
theCustomers.customers contains all customers in IBankingService.customers where theNameString[i] matches IBankingService.customers.surname[i] (where 0 <= i < length(theNameString)).
Variants:
None.
Use case <<update service>>: "add transaction" (in: theTxType, theTxValue, theAccount, theCheckNo)
In:
theTxtypethe type of the transaction to be added
theTxValuethe value of the transaction to be added
theAccountthe account to which the transaction is to be added
theCheckNothe check number, if applicable
Objective:
to add the specified transaction to the specified account
Precondition:
theAccount must be a valid account in the system
… etc.
Postcondition:
A transaction t (of the appropriate type) is added to theAccount.transactions, where t.value = theTxValue, t.checkNo (if applicable) = theCheckNo.
Variants:
Other transaction types are envisaged in the future.
Note that the <<service>> use cases are specified against the specification model in Figure 7.
Figure 7. Specification model for retail banking system.
WHY USE THE RSI APPROACH? It provides a framework for decision making regarding the appropriate "granularity" and "content" of use cases. It is not the intention of the RSI approach to mandate that all three use case types be specified at all times. Such decisions must be driven by project needs such as size, skills availability, criticality, etc. The RSI approach provides a framework within which conscious decisions can be made as to what level of detail of use case is appropriate for a particular project, and provides clearly defined placeholders for all major specification deliverables.
It encourages software reuse. The RSI approach assists in presenting a component-oriented view of a system. The <<service>>/<<interface>> split facilitates intersystem integration by easing the addition of new interfaces on the system.
It assists in team structuring. The RSI approach assists in the separation of roles among business-oriented nontechnical analysis staff (who would undertake <<requirement>> use case definition), design-oriented staff (who would undertake <<service>> use case definition), and user-interface specialists (who would undertake user <<interface>> use case development).
It provides for rigorous requirements traceability. The RSI approach provides traceability between the requirements driving the system definition and the <<service>>/<<interface>> implementing them. This can be particularly beneficial in evaluating the cost of requirement changes.
OTHER ISSUES
Separating <<Interface>> and <<Service>> The separation of <<interface>> and <<service>> use cases is functional (although in some circumstances it may also be mirrored by an architectural split between the client and server elements of multitier systems), and so it falls within the scope of the use case analysis. The separation of <<service>> and <<interface>> use cases partitions functionality into the elements that are primarily concerned with manipulating the peculiarities of an interface and the elements that are fundamental to the system in question. The motivations for this separation are twofold: to encourage the reuse of <<service>> use cases (from a variety of <<interface>> use cases), and to enable a clear factoring out of interface concerns in the specification process.
In some cases the <<service>>/<<interface>> separation is clear-cut, most often when the actor is a human user. In other cases things are not quite so straightforward. Consider the retail banking example. A requirement exists for a file of transactions to be read and entered into the system. Is the file-parsing activity a <<service>> or an <<interface>> use case? To answer this type of question, consider what aspects of functionality would change if the nature of the detail of the interface changed. The aspects that remain constant constitute part of the <<service>> use case set; the aspects that vary constitute part of the <<interface>> use case set. Accordingly, the file-parsing activity in the "interbank transfer" use case (see Fig. 6) is part of an <<interface>> use case.
Two-Phased Approach to Use Case Analysis From a process perspective, two phases of use case analysis emerge: high-level <<requirement>> use case gathering and detailed <<service>> and <<interface>> use case specification. <<service>> and <<interface>> use case definitions are undertaken in parallel, as <<interface>> use cases drive the definition of the set of <<query service>> necessary in the system.
The process of moving from <<requirement>> use cases to <<interface>>/<<service>> use cases involves both scoping and refinement. A decision is made as to which steps in the <<requirement>> use case are to be automated. These are then refined into <<service>> and <<interface>> use cases.
It is interesting to note that this process has a related parallel in the transformation of a conceptual object model into a specification model. <<requirement>> use cases are at the level of abstraction of conceptual object models; <<service>> use cases are at the level of specification models.
<<Interface>> Drives <<Query Service>> Definition <<interface>> use cases use <<query service>> use cases to locate objects that need changing, and <<update service>> use cases to perform the changes. <<query service>> use cases provide functionality useful in ensuring that the preconditions of <<update service>> use cases are met.
The set of <<query service>> use cases required in a system will vary depending on the exact nature of the interface. Consider two interfaces to an <<update service>> "delete customer." A dumb terminal interface requires the user type in the customer number, which will then be validated before a deletion operation is carried out. To do this it might use a <<query service>> "check customer exists using customer number." Alternatively, a GUI-style interface would be more sophisticated (perhaps similar to the interface described in use case interface "process inter-bank transfer file"), building up lists of customers on the screen. To do this, it might use a <<query service>> use case such as "get all customer by name."
Figure 8. The RSI use case analysis process.
Figure 9. Scoping and refinement of models.
CONCLUSION The RSI approach has been used successfully by Ratio Group on several projects of varying sizes. The RSI approach addresses a number of issues often ignored in classic descriptions of use case analysis, and in particular:
- suggests two "levels" of granularity that may be used for use cases: the <<requirement>> levelconcerned with high level scoping of system requirementsand the <<service>>/<<interface>> levelconcerned with the detailed specification of the system.
- provides clear guidelines on how use cases should be decomposed, and when decomposition should stop: <<requirement>> use cases generally being broken down into a number of detailed <<interface>> use cases, which in turn are broken down into their constituent <<service>> use cases. <<service>> use cases may be subdivided, but only where the subdivision is into additional <<service>> use cases, which are useful in their own right!
- provides a clear placeholder<<interface>> use caseswithin which user or external system interface-related functionality, such as dialog boxes, user interface dynamics, report layouts, interface protocols and interface file formats, may be described if required.
Postscript Fowler2 discusses the difference between what he calls "user goals" and "system interactions" (in RSI terms these are akin to the <<requirement>>/<<service>> split). Cockburn3 talks about the difference between "dialog interface" and "semantic interface"perhaps akin to the <<interface>>/<<service>> split of RSI.
Acknowledgments I would like to thank Thomas Mowbray, Pete McBreen, Steven Kefford, Alan Williams, Hubert Matthews, and Greg Gibson for their work in reviewing the first draft of this article. Their comments were invaluable and led to a substantial reworking of this article.
Particular thanks are due to Benedict Heal, whose work on the Catalysis and its approach to use cases had a major impact on the ideas presented in this article.
References
- Jacobson, I. et al. Object Oriented Software EngineeringA Use Case Driven Approach, Addison-Wesley, Reading, MA, 1992.
- Fowler, M. UML Distilled, Addison-Wesley, Reading, MA, 1997.
- Cockburn, A. "Structuring Use Cases with Goals,"
http://members.aol.com/acockburn/papers/usecases.htm.
- Short, K. Component Based Development and Object Modeling, Texas Instruments.