next up previous
Next: Patterns of Use Cases Up: Essential Use Cases and Previous: Use Case Responsibilities and

Example

 

In this section, we present a small example to illustrate how our approach works. This design is for a small part of a library system. The domain model consists of two classes of objects: books and borrowers. Figure gif shows the sequence of steps. At the top, we have identified the two focal use cases: borrowing and returning a book.

 

  figure193


Figure: Tracing responsibilities from essential use cases to design.

Consolidating the system responsibilities of just these two essential use cases results in a system object, which we show as a CRC card (marked ``Iteration 1''). It is important to be aware that not all responsibilities of the system object will be explicit at this point. For example, in order that the system verify that the book may be borrowed, the system has the implicit responsibility to record what books are borrowed. Implicit responsibilities will typically be identified when they are distributed to the collaborating objects.

While the system object must clearly be able to enact the two use cases, if we had more use cases the resulting object would be large and unwieldy to implement. Considering the domain model, we could construct a design using three classes, a singleton Library System class, a Book class (one instance per book) and a Borrower class (one instance per borrower). We now need to decide how the responsibilities are distributed between the classes.

Iteration 2 shows the CRC cards for this design. There are several points we should note. For example, the implicit responsibility of recording whether or not a book has been borrowed has now been made explicit, and delegated to the Book class. Furthermore, the responsibility of updating whether or not the book has been borrowed has also been moved to the Book class. Note however that the Library System still has the responsibility of initiating the check and record update, which together may be regarded as the responsibility to issue the book.

The Library System has also acquired another responsibility that was not apparent in the original system object, that of ``knowing all books'', that is, being able to locate a Book instance given its identity (such as call mark). This responsibility has become important because we have created the Book class, and so the Library System must now become responsible for managing the Book instances. The situation with Borrower is similar.

Further consideration of the design could see the ``knowing all books'' responsibility moved into a separate singleton Catalogue class, perhaps implemented with a standard Collection object (Iteration 3, with the Book and Borrower classes unchanged).

One final point to make with this example is that we have only listed responsibilities as identified by the use cases. In reality, when we develop the domain model we will usually identify other responsibilities that the classes are likely to have. This information would also feed into the process described above. For example, recording whether or not a book is borrowed is a responsibility very likely to be identified from the domain analysis.

As the figure shows, tracing the responsibilities from the requirements through to the different designs is not only straightforward, but naturally falls out of the design decision making process. This is useful for communicating with stakeholders, and in particular when carrying out reviews.


next up previous
Next: Patterns of Use Cases Up: Essential Use Cases and Previous: Use Case Responsibilities and

Robert Biddle
Sun May 20 12:22:36 NZST 2001