If you are eventually going to code up your system in an object-oriented fashion, you need the classes from which to create objects. Where could you possibly figure out what classes you need? Your domain model!
By working from your use case descriptions, you can design your classes via a class diagram. As you'll see, a class diagram will contain a set of classes and their relationships. Let's get to it!
Step 1: Identify Your Nouns
Like you saw in Part 1, a use case description describes the sequence of interactions between the user and the system. It can be at any level of detail that you need. It's pretty simple. The user does something, the system responds. Over and over, until the goal is reached. Recall the use case description for "Searching for a book." Notice that I've detailed the system results and highlighted the nouns:
The user requests to search for a book.
The system displays the search page.
The user enters the author’s name.
The system verifies that the author’s name exists.
The user enters the title of the book.
The user requests, the search executes.
The system searches.
The system displays the results:
A collection of books that match.
An image of the cover of each book.
A short author bio.
An image of the author.
Once you have that interaction written out, you can play a game of spot the noun. Let's define two kinds: sophisticated/complicated or simple. If the noun is sophisticated (it can't be described in a word or two), it's likely to be a class in an object-oriented language. If it’s a simple noun, then it will probably be an attribute of a class.
For example, a book seems like it would be a class with several items associated with it (author, title). It can't be represented as an integer or string. Conversely, the title appears simple and probably just a string. It will be an attribute, but of what? Well, we say it's the "title of a book." So, it will be an attribute of the class book.
What if I get it wrong?
That's OK. It's a kind of art and not straight science. Very often, something seems like it will be a class (or attribute), but when you implement it, you realize that it's simpler or more complicated than you thought!
An example here is the author. Currently, it's just the name of a person, so you can make it an attribute of book. But in a future use case, you may discover you have much more information about the author, like date of birth, the list of all their books, maybe a brief historical description. At that point, the author would switch to being a class.
What about user and system? Are those classes, too?
First, the easy one: system. Since that's what you're building, it's not going to be a single class. It's going to be the collection of classes you come up with, working together.
Now, the user. Depending on your system, you might have different types of users (librarians, patrons) who have access to different parts of the system. You would want to have classes represent their different capabilities/access rights; however, you traditionally wouldn't have a class named user.
Step 2: Represent Your Nouns as Classes or Attributes
Once you've got your nouns defined, you can start designing classes. You represent a class as a rectangle, with the name of the class at the top, and the attributes underneath. Let's start with the book class.
There are more nouns to deal with. Let's add the user. But you don't know which user is doing this search. So far, you know of two user types: patron and librarian. Let's add them:
Here's a tricky one: the author's name. Looking at just the initial use case description, you would make the author's name an attribute of book. But if you check out the search results, you see that there is more to an author than their name. For example, they can be associated with many books. If your clients want a short bio of authors or a photo of the author, you add that:
As we walk through the scenario, you’ll recognize that some classes must communicate with each other to search for a book. There must be a relationship between them. You represent that with a line between the classes. Check out the diagram below:
What are those little ones and that asterisk doing? 🤔
Ha, you noticed that, did you? 😎In the example, the search results have a bunch of books. Using UML, you'd notate that with an asterisk, which represents one or more. Since, again, you're talking about the books, you put that asterisk where the relationship line intersects with the book class. Meanwhile, a book only has one search result. So you put a 1 where the relationship line intersects with the class "search results."
Now you give it a try! How would you notate the relationship between book and author? What about the relationship between image and author? Image and book? Once you've got an idea, check out the image below:
Each book has an author. An author may have written many books, but a book typically has a single author. So, you can annotate your line with * next to book and 1 next to the author. A book would have one image associated with it, as would an author.
After reading through one or more use case descriptions, your class diagram will add more classes and relationships. If other use case descriptions talk about a book's ISBN, images, or the personal history of an author, you can add it to your classes as attributes!
Try It Out for Yourself: Use Case to Class Diagram Challenge!
Now that you've seen how these works, let's practice transforming a few more use cases into a class diagram. While your patrons need to search for a book or pay late book fines, your librarians asked for the following use cases:
Generate late book report.
Fine account for lateness.
Purchase replacement book.
Collect patron fines.
Let's design the first two together. 😀 Let's start with "generate late book report:"
Generate Late Book Report
Create a class diagram from the following use case description:
The user selects the late books page.
The system displays the page.
The user enters the patron's name or Id number.
The user selects search for late books.
The system searches:
A late book is one that is checked out by a patron, and has not been turned back in before the due date.
The system presents a list of late books.
The user selects print.
The system prints the list.
Once you've finished designing the classes for this use case, check your results against the solution below. Don't forget to notate your 1's and asterisks!
Solution: Generate Late Book Report
First add the patron class:
You already have a concept of a book. Now you need to add the idea of a checked-out book - one that has a due date. Also, how does a book become checked out? Well, it's done by a patron! So you should associate your checked-out book with a patron.
A patron may have many checked-out books, right? That's how it's indicated in the solution! Lastly, there is the list of late books:
Why a separate "Checked Out Book" from the book class?
It is a separate concept. A book has a title, ISBN, author, etc. But the idea of it being late with a fine does not apply to all books.
Ok, now let's work through one more example: fine account for lateness.
Fine Account for Lateness
The fine account for lateness is very similar to generating the late book report. But rather than looking at a single user account, it searches for all patrons that have books out beyond the due date.
The user selects the late books page.
The system displays the page.
The user selects generate fines for overdue books.
The system searches:
A late book is one that is checked out by a patron, and has not been turned back in before the due date.
The system traverses the list, calculating each patron's fine.
The system sends an email to each patron, containing the list of late items, and the total cost of the fine(s).
Once you've finished designing the classes for this use case, check your results against the solution below. Don't forget to notate your 1's and asterisks!
Solution: Fine Account for Lateness
First add an email attribute to each patron:
Now you need to add the idea of a late book (a checked-out book that has not been returned before the due date). Late books also have a fine associated with them. At this point, that seems simple enough to be an attribute. Here's the completed class diagram:
Let's Recap!
Here's how to make a class diagram:
Start with the use case description. Find the important ideas (classes) and lesser ideas (attributes of classes).
Add a rectangle for each class and list the attributes underneath.
Connect classes with meaningful relationships via lines.
Notate whether there is one of something or many with 1s and asterisks.
A class diagram is ever-evolving. As you understand more use cases, you will add more classes and attributes. You may even move attributes from one class to another. That's all part of the process! 🙂
In the next chapter, we'll take a look at modifying the diagram when the librarians come up with new functionality.