0% found this document useful (0 votes)
90 views56 pages

Introduction To UML

This document provides an introduction to the Unified Modeling Language (UML) and how it can be used to design software projects. It uses a cash register project as an example to demonstrate modeling with UML diagrams, including use case diagrams, class diagrams, and sequence diagrams. The document also discusses how object-oriented programming concepts like classes, objects, attributes, and operations relate to UML modeling and how designs can later be implemented in an object-oriented programming language like Java.

Uploaded by

tj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
90 views56 pages

Introduction To UML

This document provides an introduction to the Unified Modeling Language (UML) and how it can be used to design software projects. It uses a cash register project as an example to demonstrate modeling with UML diagrams, including use case diagrams, class diagrams, and sequence diagrams. The document also discusses how object-oriented programming concepts like classes, objects, attributes, and operations relate to UML modeling and how designs can later be implemented in an object-oriented programming language like Java.

Uploaded by

tj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 56

Introduction to UML

(Reader for course INF-32306 Software Engineering)

Dirk L. Kettenis
Mark R. Kramer
Roberto Rossi

Information Technology Group, Wageningen University

March, 2011

1
Table of contents
1. Introduction ........................................................................................................................ 3
1.1. Preparing software...................................................................................................... 3
1.2. Object-oriented programming .................................................................................... 3
1.3. UML ........................................................................................................................... 4
1.4. Software production ................................................................................................... 4
1.5. Case ............................................................................................................................ 5
2. System description ............................................................................................................. 6
2.1. System description of the cash register project .......................................................... 6
3. Use case diagram ................................................................................................................ 8
3.1. Actors ......................................................................................................................... 8
3.2. Use cases .................................................................................................................... 9
3.3. Use case diagram of cash register ............................................................................ 10
3.4. Textual description of the use cases ......................................................................... 10
3.5. Priority of use cases .................................................................................................. 13
3.6. Some other use case diagrams .................................................................................. 14
4. Class diagram ................................................................................................................... 17
4.1. Detection domain concepts ...................................................................................... 17
4.2. Selection of classes ................................................................................................... 18
4.3. The class diagram ..................................................................................................... 21
4.4. Naming the associations and navigability ................................................................ 22
4.5. Multiplicities ............................................................................................................ 23
4.6. Some remarks about class diagrams......................................................................... 25
4.7. Attributes .................................................................................................................. 26
4.8. The class diagram without SalesLineItem................................................................ 28
4.9. More attributes ......................................................................................................... 29
4.10. Identification of operations .................................................................................. 30
4.11. CRC cards ............................................................................................................ 31
4.12. Generalization ...................................................................................................... 34
4.13. Generalization versus composition ...................................................................... 37
4.14. Polymorphism ...................................................................................................... 37
5. Interaction diagrams ......................................................................................................... 41
5.1. Sequence diagram .................................................................................................... 41
5.2. A sequence diagram for the cash register project .................................................... 43
5.3. Searching the Item object ......................................................................................... 45
5.4. Relation with the class diagram ............................................................................... 46
5.5. Separation of GUI and engine .................................................................................. 50
5.6. Communication diagram .......................................................................................... 50
6. Implementing cash register project .................................................................................. 54
6.1. Reuse of software components ................................................................................. 54
6.2. Data structures needed for the cash register project ................................................. 54
6.3. Some other implementation issues ........................................................................... 55

2
1. Introduction
The production of useful, usable, and reliable software is a complex task. Using the right tools
is for programmers a prerequisite for completing the tasks successfully and in time.
Preparation of software starts with a design of the program. UML is a “graphical language”
useful in the design phase of a software project. To implement the design into a program we
need a so-called programming language. For this course we have selected the programming
language Java. Java is a so-called object-oriented programming language. Nowadays, Java is
the programming language most frequently used for production of professional software.

In this document we introduce you to UML. We do that on the basis of an example. With the
help of the UML notation we will prepare the design for the example system. In one of the
later chapters we present the implementation of the project with the help of the programming
language Java. The design of the program, however, does not depend on the programming
language used for the implementation. During the discussion, we sometimes will refer to
programming language constructs. Because Java is the language of our choice, we use the
Java terminology at those spots.

1.1. Preparing software


There are several ways to categorize the production of computer programs. Among others,
one may distinguish “programming in the small” and “programming in the large.” One uses
the term “programming in the small” when a program is needed to solve a relatively simple
problem and the program is needed only a couple of times. Researchers meet such a situation
frequently. If the problem has been solved, the software is not needed anymore. Maintenance
of this type of software is not an issue. If program is more complex, the program will be
produced for a customer,1 or both one uses the term “programming in the large.” Maintenance
of this type of software is important. For this type of software, the object-oriented
implementation is desirable. Most probably, the software will be produced by a team of
programmers. Therefore, a thorough design is needed. In this document, we will discuss
techniques useful for the design of programs of the category “programming in the large.”

1.2. Object-oriented programming


Assume you want a contractor to build a garage for you. After the design phase, the contractor
starts building the garage. For this task some craftsmen are needed, for example a bricklayer,
carpenter, electrician, garage door mechanic, and a plumber. Most probably more bricklayers
and carpenters are working at the same time to deliver the garage in time. Every craftsman is
able to perform several tasks. The bricklayers, for example, have the tasks to lay the
foundation, construct the floor, and lay bricks. The carpenters, have the following tasks: set
window frame, set door frame, install window, install door, and construct the roof. The
contractor employs a works foreman to plan and coordinate the work of all involved
craftsman. The works foreman gives orders to the craftsmen and checks whether they have

1
A customer may be a division in the organization where you work or an external organization.

3
performed their tasks correctly. The works foreman leaves the way the craftsmen perform
their tasks to the craftsmen.

In fact, this is the way an object-oriented program will work. In an object-oriented program,
objects are performing some tasks and all objects active in the program together perform the
task of the program. How an object performs the task is the responsibility of the object itself.
In this respect an object in a program is comparable to the craftsman in the building process.
An object has variables to store information and an object is able to perform some operations.
The variables are called attributes and the operations are the responsibilities of the object.
Like all bricklayers have the same responsibilities, some objects may have the same
responsibilities and have attributes in common. In object-oriented terminology, we say that
these objects belong to the same class. In the implementation of a program, the programmer
defines the classes. A class does nothing; one needs an object to perform the tasks. Therefore,
in the program one or more objects may be created. Such an object is sometimes called an
instance; it is an instantiation of the class. Every object of one class has the same attributes
and the same operations. Different instantiations of one class, however, may contain different
values in corresponding attributes. To perform a task, an object may need the service of
another object. In such a case the object that needs service of another object sends a message
to the other object. After the other object responds, the object may continue with the tasks of
the object itself. How the other object performs the task is not of interest. In object-oriented
programming terminology we call this encapsulation. Encapsulation means that details about
how a task is performed are only known to the object itself and is hidden for other objects.

1.3. UML
UML is short for Unified Modeling Language. During the design of a software system with
the help of UML, one prepares several models of the system. Every model will be represented
in one or more diagrams. We will discuss the following diagrams: use case diagram, class
diagram, sequence diagram, and communication diagram. In this document, we use UML 2.0
notation. The UML 2.0 notation is similar to previous notations. Some minor details differ.
For example, in previous versions, the communication diagram was called collaboration
diagram.

1.4. Software production


To prepare software, the first thing to do is to find out what the customer wants. For that
purpose, we prepare a description of the system to be produced. We have to discuss this
system description with our customer, to make sure that we and the customer understand what
the system is supposed to do and what should be included in the system. The next document
to prepare is the use case diagram and a textual description of the use cases. This needs also
feed back from the customer. The purpose of the use case document is to get the requirements
of the system clear. The design of the software, in fact, starts with the preparation of the class
diagram. A class diagram depicts the static structure of the software system. The dynamical
behaviour of the software system is depicted in several interaction diagrams. The procedure
sketched is not a linear process where all mentioned phases follow each other in the given
order. Frequently, we have to reiterate the process partly or completely.

Design of software, like other design oriented tasks, is not an exact science. During the design
process several decisions have to be made. Frequently, several decisions that lead to a good
design are possible. We will present a design that, from our perspectives, is a good design.
Most likely, other design teams will end up with another design.

4
1.5. Case
In this text we will develop a design of software for a supermarket cash register. The general
idea of this example has been published before in Larman.2 The design presented here,
however, differs in an essential way from the design by Larman.

A cash register is a system that records sales and handles payments. Such a system consists of
several hardware components: computer, display, printer, and bar-code scanner. Furthermore,
the system will not work without software. We will illustrate different UML models and the
role they play in the development of the software system in general and for the cash register in
particular.

2
Larman, Craig, Applying UML and patterns: an introduction to object-oriented analysis and design, Prentice-
Hall Inc, 1998, ISBN 0-13-748880-7.

5
2. System description
The first thing to do is to prepare a description of the software to be produced. This system
description will be discussed with some people working on the project and with (a team of)
the customer. The discussion with the customer is important, since it is of utmost importance
that we deliver a system that does what the customer has in mind. In practice, however,
customers develop new ideas while the project evolves. So, most probably, the customer will
come up with new requirements that may turn the design of the software system upside down.
Ideally, designing should start only if the system description is clear and the customer agrees
about the system requirements. The use case diagram we will discuss in the next chapter plays
an important role in deciding the system requirements. Most probably, several iterations are
needed to fix unclear parts of the description and make the requirements of the customer
complete.

The system description is a concise description of what the system is supposed to do. One
should not include implementation details. Or in other words: specify what the system does
and not how. Formulate the description as clearly as possible. Therefore, write short sentences
and use active sentences. For example the active sentence “The user presses a button” is better
than the passive one “A button will be pressed by the user” or even worse (but very common)
“A button will be pressed.”

2.1. System description of the cash register project


The shortest system description for the cash register project we can think of is:

“The system records sales and handles payments.”

This description is correct, however, it is a high level description and it is not very useful. We
need another more detailed system description. Such as:

“If a customer arrives at the checkout to pay various purchase items then the
cashier records the bar-code number of each item as well as the quantity if it is
greater than one. The cash register displays the price of each product and its
description. Customer card holders pay reduced prices for certain products.
When all products have been recorded, the cashier indicates the end of sale. The
cash register computes and displays the total cost of the purchases. The cash
register indicates how much change the customer is to be given. The cash register
records the sale and prints a receipt. Every morning, the manager initializes the
system. At the end of the day, the manager makes up the cash and closes the cash
register. At the start of the working period, the cashier logs in with an ID and
password. At the end of the day the cashier logs out.”

6
We could add to the description:

“The cashier takes money from the customer, enters the amount in the payment
field and puts it in the cash register.”

This sentence contains information that is outside the scope of the software. The software has
nothing to do with handling bank notes and coins. The task of the cashier, however, is to
make sure that the correct amount of money is in cash. This sentence contains another error: it
also indicates how something takes place: “….enters the amount in the payment field….” In
the description we could, for example, list that the manager takes some money to the bank.
Here, the software is not involved either, so we leave that out of the description.

As indicated before, we need to discuss the system description with the customer and make
sure that the customer is satisfied. Important is that we make sure that the customer has
thought thoroughly about the system requirements and the customer will not come up with
new requirements during the implementation phase of the project. To help to make sure that
the system requirements are satisfactory for the customer, UML has the so-called Use case
diagram. We discuss the Use case diagrams in the next chapter.

7
3. Use case diagram
The use case diagram models the system from the user’s perspective. The main purpose of a
use case diagram is to define the requirements of a software system in close cooperation with
the customer. Therefore, the symbols used in the use case diagram are simple and meant for
non computer specialists. We have to discuss the use case diagram and its accompanying
description with the customer to make sure that the customer understands us, we understand
the customer, and the requirements are complete and consistent. The requirements to be
complete mean that the customer does not come up with new requirements during the next
phases of the design and implementation of the software. In practice, however, the customer
will develop new requirements.

A use case is one task executed by the system. A use case is connected to an actor, which is a
person that initiates the task.

The first thing we have to do to prepare a use case diagram is to determine the actors in a
system. Next step is determination of the tasks (use cases) and to relate the tasks to the actors.

3.1. Actors
In this context, the term actor may be misleading. Like in a drama or movie an actor may play
more than one role. In fact, we are interested in the roles in the system. Since in UML a role is
called an actor, we will use both terms interchangeably.

It may help to ask the following questions to discover the actors in a system: 1) who is
interested in a certain requirement, 2) where in the organization is the system used, 3) who
benefits from the use of the system, 4) who will supply the system with information, use this
information, or remove the information, 5) who supports and maintains the system, 6) does
one person plays several roles in the system, and 7) do several people play the same role.3

What are the roles in the cash register system? In the system at hand we might consider the
following roles: customer, cashier, and manager. This information follows from the system
description given in Chapter 2. May we think of other roles in the system? In the system
description we read that at the start of the working period the cashier logs in. To be able to log
in, the system needs an account. Who or what is responsible for creating an account and the
ID and password connected to this account? This question may be raised during one of the
brain storm sessions we have with the customer or the persons representing the customer.
Normally, a person called system manager will do that task. So, there is an additional
potential actor in the system at hand.

3
A system may have non-human actors as well. To detect such actors the question “does the system use an
external resource?” may be of help. We will discuss non-human actors shortly.

8
Now we have the following potential actors: customer, cashier, manager, and system
manager. We have to evaluate for every potential actor whether they are real actors in the
system at hand. First consider the customer. Of course, the customer plays a role in the shop,
because without customers nobody will buy anything, and therefore, will not arrive at the
checkout. The question now is: does the customer play a role in the software system? The
answer to that question is no, the cashier interferes with the system for the customer. So, the
customer is not an actor. We may say that the customer is outside the scope of the (software)
system.

The cashier interferes with the system and, therefore, plays a role in the system. The manager
initializes the system every morning and closes the system at closing time, so, the manager is
an actor as well.

Now we will discuss the system manager. We may think that the manager of the shop may
play this role. In fact that may be the case. Will that mean that the system manager is not an
actor? The answer on this question is no! The roles manager and system manager may be
played by the same person, however, the manager and system manager are quite different
roles. The same is true, for example, in the Monopoly game. One of the players will be the
manager of the bank. Player and manager of the bank, however, are different roles.

Recall that it is not the person that is an actor in a system, the role the person plays is
important. In the Monopoly game, for example, the role of the banker may become another
player without effect on the game.

In the preceding text we have discussed human actors. A system, however, may have non-
human actors (devices) as well. Detection of a person as an actor in a system is relatively
easy, detection of non-human actors is more difficult. The question: “does the system use an
external resource” may help in finding the non-human actors. In this system the bar-code
reader is a candidate non-human actor. Does the bar-code reader act in the system? Of course,
the bar-code reader reads in the bar code and is important in the system. The cashier,
however, initiates the task. So, the bar-code reader is not an actor in the system at hand. An
example non-human actor is a clock that initiates a task at a predefined time.

So we end up with three actors in this system: cashier, manager, and system manager. The
next steps in the design process are finding the use cases in the system at hand and relate the
use cases with the actors.

3.2. Use cases


A use case is one task executed by the software system. Now we will list the tasks the actors
are involved in. The cashier is involved in: sell items, log in, and log out. The manager is
involved in the tasks: start up, make up the cash, and shut down. The system manager is
involved in the tasks: manage users.

You may ask whether the manager is involved in log in and log out. Indeed, we may expect
the manager need to log in and log out. In principle it is good practice to design the system
such that only one actor is involved in each use case. Therefore, we imply that the use case
start up includes log in and shut down includes log out. Other solutions are possible, however,
these require some advanced UML notation. In fact the same holds for the system
administrator.

9
In principle it is a good idea to view the tasks not on a too detailed level. For example, we
could split the task for the system manager into two tasks: create new user and delete a user.
Since these tasks are not complex, we take them together in one task.

3.3. Use case diagram of cash register


It is common practice to collect the information about the actors and use cases in a use case
diagram. Apart from the diagram, one produces a text with a description of the use cases. The
use case diagram is depicted in Figure 3-1. The large rectangle represents the so-called system
boundary. Everything in the rectangle is part of the system and what is not included in the
rectangle is outside the system.4 In the upper right corner of the rectangle the name of the
system is written. In a use case diagram, an actor is represented by a person-like symbol. This
representation of an actor strengthens the impression that an actor is always a person. An
actor frequently is a person, however, as indicated before, devices may be actors as well.
Below the actor one specifies in text the role of the actor. The actors are positioned outside of
the system boundary to highlight that the actors interfere with the system and are not part of
the system. A use case is represented by an ellipse with some words in it to indicate the use
case. A line connecting an actor and a use case indicates that the actor initiates the use case.

3.4. Textual description of the use cases


To prepare the textual description of the use cases it is useful to determine the prerequisites to
be fulfilled before the use case can be executed, determine the interactions with the user, and
consider the exceptions. In the sequel we will present the use case descriptions of the cash
register project. We use here a format we thought to be useful. In UML the format is not
specified, so we may select a format that suits us.

Use case: Sell Items


Actors: Cashier
Description: A customer arrives at a checkout with items to purchase. The cashier records
the purchase items, accepts money, and, if needed, returns change.
Exceptions: Bar code cannot be read or is not known.
Customer is unable to pay.
Cashier is unable to give change.

A prerequisite to be fulfilled for this use case is the arrival of a customer at the checkout. In
this use case the interactions with the user are payment, so money goes from the customer to
the cashier and, if needed, the cashier gives change. The exceptions are described clearly. If
the bar-code reader cannot read the bar code, the cashier can enter the bar code manually.
What the cashier has to do when the bar code is not known is left open in the description of
the use case.

The text of the description of a use case should be concise and without details on how the task
is performed. So, in the description of the use case Sell Items we list “The cashier records the
purchase items.” We, however, do not include that the cashier does that with the help of a bar-
code reader.

4
Some people do not draw a system boundary in a use case diagram. UML does not prescribe to include the
system boundary in a use case diagram. We, however, think the use case diagram should include the system
boundary.

10
In the system description given above nothing is written about recording the inventory items.
To limit the complexity we have left that out of the system requirements. Assume that one of
the tasks of the software system was to keep the number of inventory items up to date. Then
we have to decrease the inventory quantity in stock depending on the number of items bought
by the customer. Furthermore, if new items arrive, we have to update the number of inventory
items according to the number of items that arrive. In such a system an exception might be
“Number of items in stock becomes negative.” Such an exception is rather peculiar. How is it
possible that a customer comes to the checkout with an item to purchase while that product is
out of stock? Several sources may be responsible for this error. For example, the software
responsible for the administration of the stock does not operate correctly or updating the stock
has not taken place.

Use case: Log In


Actors: Cashier
Description: A cashiers logs on to the system by presenting his account name and password.
Exceptions: Account name does not exist.
Password is not correct.

Use case: Log Out


Actors: Cashier
Description: A cashier logs out.
Exceptions: No exceptions.

Use case: Start Up


Actors: Manager
Description: A manager powers on the cash register in order to prepare it for use by Cashier.
The manager validates that the date and time are correct after which the system
is ready for Cashier to use.
Exceptions: Date is not correct.
Time is not correct.
System does not start up.

The last exception of the use case Start Up (“System does not start up”) may have several
causes. However, the manager cannot do much about those causes. Most probably an expert is
needed to solve the problem. The only thing the manager may do is to restart the system
again.

We may formulate the description of the use case Make Up the cash as given below. The
formulation, however, is not correct. This is because handling of money is outside the scope
of the (software) system.

Use case: Make Up the Cash


Actors: Manager
Description: The Manager makes up the cash and takes some money to the bank. The
Manager leaves some change in the cash register.
Exceptions: The balance is not correct.

11
Cash Register

Sell Items

Cashier

Log In

Log Out

Manager
Start Up

Make Up the
Cash

Shut Down

System Manage Users


Administrator

Figure 3-1 Use case diagram of Cash register

The only part that should be included in this use case description is the fact that the software
does the necessary computations. A correct formulation of the use case is:

Use case: Make Up the Cash


Actors: Manager
Description: The Manager makes up the cash.
Exceptions: The balance is not correct.

12
Use case: Shut Down
Actors: Manager
Description: The Manager shuts down the cash register.
Exceptions: No exceptions.

Use case: Manage users


Actors: System Administrator
Description: The System Administrator logs on to the system giving account name and
password.
The System Administrator adds a new account, removes an existing account, or
changes an existing account.
The System Administrator logs off the system.
Exceptions: The System Administrator’s account name, password, or both are incorrect.
The account to be changed or deleted does not exist.

3.5. Priority of use cases


Preparing a software system is a long lasting effort. Successful completion of the project is in
our interest and in the interest of the organization we prepare the software for. Our interest,
most probably, is to earn as much money as possible. That includes that we want to finish the
project completely. Because of the time span needed to finish a software program
successfully, the customer sometimes will stop the project in case the customer thinks the
progress of the project is too slow or the customer loses confidence that the software is able to
perform the tasks the customer has in mind. Therefore, it is wise to start the project with
implementing the use cases that are the most important ones for the customer. In this respect,
it is a good strategy to start with the use cases that the person responsible for providing the
money finds most interesting. It is wise to show the customer that the use cases implemented
work and are profitable for the organization of the customer. Another point to take into
account when deciding the priority of the use cases is to implement the software in such an
order that the system operates. Furthermore, it is important to give priority to the use cases
that are difficult to implement. If we have shown it possible to implement the most difficult
use cases then the customer will believe we are also able to implement the less difficult use
cases.

For the software project at hand a suitable priority of the use cases is as follows:
1. Sell Items
2. Make Up the Cash
3. Manage Users
4. Log In and Log Out
5. Start Up and Shut Down

We should indicate reasons for the priorities we give to the use cases. In the cash register
project the use case Sell Items is the most important one. It is the most difficult as well. This
use case is the key one; without this use case the software will be useless. An additional
reason to put the use case Sell Items at the highest priority is that training of the cashiers may
start before the system operates completely. If training of the staff starts early, the system may
become operational after the software has been completed. At position 2 we have listed the
use case Make Up the Cash. The reason for this is that earning money is the key business of
the shop. The other use cases have to do with security issues. The system will work without
the possibility to add new accounts, for example. If the system has no possibility to add new

13
accounts, the cashier cannot log on to the system. Consequently, everybody may use the
system and, most probably, the system becomes corrupt. Important, however, is that we can
show that the most important use case(s) operate(s) well.

The use case Manage Users has priority 3. Before a cashier may log in, the software system
needs to know the accounts of all people allowed to log on to the system. Therefore, the
account names and passwords should be known to the system. So, it makes sense to
implement use case Manage Users before we implement the other use cases. We could put the
Start Up and Shut Down on priority 3. The only action performed by the software system is
updating the date and time. The system may operate in a safe way without a correct day and
time, so we position this use case as the one with the least priority.

At position 4 we have put the use cases Log In and Log Out. The use case Log In should
come first, but these use cases are relatively simple and related so that we can better
implement them together. Moreover, we may consider implementing the use cases Start Up
and Shut Down before we implement the use cases Log In and Log Out. Again, the use cases
Start Up and Shut Down are relatively simple, so they can be implemented without much
effort. Therefore, ranking the use cases Start Up and Shut Down on priority 4 is not an error.

Some readers may think that the use case Log In deserves the highest priority. The idea here
is that the operation of the system starts with the use case Log In. This makes sense, however,
is not correct. In the process of giving priorities to use cases, we should put the use cases that
provide useful functionality for the users at the highest priority. The system may operate well
without implementation of the use case Log In. Without the use case Log In, the system will
operate not as safe as it could, but the system does something useful for the company that
needs the software. So, the use cases Log In and Log Out only serve the security of the
system.

3.6. Some other use case diagrams


In the book Using UML5 the use of UML is illustrated with the help of a design of a software
system for a library. The use case diagram given for that software system is depicted in Figure
3-2. In the book UML Toolkit6 the use case diagram of Figure 3-3 is given for a similar
system. The differences of the two use case diagrams show that one may prepare quite
different use case diagrams for similar software systems.

A more significant difference between the use cases given in Figure 3-2 and Figure 3-3 is the
level of detail of the use cases. For example, in Figure 3-3 there are the following use cases
for the Librarian: Add Title, Remove or Update Title, Add Item, and Remove Item. The use
case diagram of Figure 3-2 displays these use cases on a higher level of detail in the use case
Update Catalog. In the diagram of Figure 3-3 we see use cases: Add Borrower and Remove or
Update Borrower. These use cases are not present in Figure 3-2. The software system
developed on base of the use case diagram presented in Figure 3-2 will not have the
functionality to administer the members of the Library. Either Figure 3-2 is not complete or
the software system build on basis of this use case diagram is not complete.

5
Stevens, Perdita and Pooley Rob, Using UML Software Engineering with Objects and Components, Pearson
Education Limited, 2000, ISBN 0-201-64860-1.
6
Eriksson, Hans-Erik and Penker, Magnus, UML Toolkit, John Wiley and Sons, 1998, ISBN 0-471-19161-2.

14
In Figure 3-3 we see no use cases related to borrowing Journals. Most probably that library
will not lend journals or the procedures for borrowing journals in that library do not differ
from borrowing books.

In Figure 3-3 there is no actor Browser and the use case Browse is not present. So, in the
system developed on base of Figure 3-3, the system does not support a computerized catalog.
Another interesting difference is that in Figure 3-3 the actor Borrower does not interfere with
the software system itself. That task has been given to the Librarian. This use case diagram
expresses the idea that the Borrower himself will not communicate with the system. Like in
the cash register system, where the customer himself will not be an actor, but the cashier will
be the actor. Furthermore, in Figure 3-3 the actor Librarian has many tasks and we think that
the authors have thought about the person that acts and not about the role the actor plays in
the system. To our opinion lending out books is quite a different role than updating the
catalog and member data base.

Figure 3-2 Use case diagram for a software system for a library according to Using UML

15
Figure 3-3 Use case diagram for software for a library according to UML Toolkit (please see comments in
text)

16
4. Class diagram
The next step in the design for the software system is to select the types of objects (these
types are the classes) that play an important role in the software. If one understands a system
well, it is easier to develop and maintain. The software system is easier to understand if
important domain concepts are the principal building blocks of the software. Therefore, it is
important to detect what the important domain concepts are. One way to detect the domain
concepts is to identify nouns and noun phrases7 in the system description and the description
of the use cases. We may discuss the software system with our customer or other domain
experts. In such a brainstorm session we may discover some additional domain concepts. In
the sequel we will illustrate the noun identification process based on the system description
given before. Next we will prepare a class diagram for the cash register project.

4.1. Detection domain concepts


The first step needed to prepare a class diagram is the detection of important domain
concepts. As indicated in the introduction of this chapter, noun identification is a frequently
used tool for this purpose. A way to proceed is underlining the nouns and noun phrases in the
system description. The system description presented in Chapter 2 with nouns and noun
phrases underlined is as follows:

“If a customer arrives at the checkout to pay various purchase items then the
cashier records the bar-code number of each item as well as the quantity if it is
greater than one. The cash register displays the price of each product and its
description. Customer card holders pay reduced prices for certain products.
When all products have been recorded, the cashier indicates the end of sale. The
cash register computes and displays the total cost of the purchases. The cash
register indicates how much change the customer is to be given. The cash register
records the sale and prints a receipt. Every morning, the manager initializes the
system. At the end of the day, the manager makes up the cash and closes the cash
register. At the start of the working period, the cashier logs in with an ID and
password. At the end of the day the cashier logs out.”

We prepare a list of all underlined words. As is clear from the description some words appear
more than once, for example cashier and cash register. We add these words only once to the
list. We may consider underlining those words only one time in the system description. Since
it is easier not to do several tasks at the same time, a better approach is to underline all
occurrences of a noun or noun phrase and later filter out multiple occurrences.

7
A noun phrase is a sequence of words containing a noun that function together as a noun as the subject or
object of a verb. Examples are “the red ball” and “the man with a black hat.” Some noun phrases appearing in
the system description are “end of sale” and “start of the working period.”

17
Another important point to be aware of is that different words may refer to the same domain
concept. Those words are called synonyms. Examples from the given system description are
purchase item, product, and item. These words express here one concept and we will call the
concept item. We may try not to add synonyms to the list, however, again it is better to filter
out those synonyms later. The reason is the same as for not underlining a word more than
once. We will filter out synonyms after we have added all nouns to the list.

Words are added to the list as singular. Then the list of words in order of appearance
becomes:

customer product receipt


checkout description morning
purchase item customer card holder manager
cashier reduced price system
bar-code number end of sale end of the day
item total cost of the purchase start of the working period
quantity change ID
cash register sale password
price

We may add to this list some concepts that rose during so-called brain storm sessions and
concepts detected from the use case descriptions. We add to the list the following words:

payment inventory quantity date


store day time
money bank account
amount end

4.2. Selection of classes


Now we have a list of candidate classes and we have to select the appropriate ones. There are
several reasons not to select a word as a domain concept important enough to select as a class.
Reasons not to accept a word as a class are:
1. The word indicates a redundant concept. A synonym is an example
2. The word is irrelevant for the software system or outside the scope of the system
3. The word is vague; normally, only concrete concepts are selected as a class
4. The word represents an event or an operation
5. The word is so-called meta-language,8 requirement (not in the system description of
the cash register project) is an example
6. The word can better be implemented as an attribute of a class
7. The word refers to an instantiation of a class (an object) rather than to a class

Reason 4 indicates that events will not be selected as a class. In the cash register project an
example is end of sale. For the cash register project and the majority of the systems it does not
make sense to implement events as a class. We know, however, of systems where events play
an important role, discrete-event simulation programs are an example. In discrete-event
simulation programs, an event will be implemented as a class. Another example where we

8
Meta-language is a language to talk about language. In this context a noun is meta-language if it is part of the
way we define things rather than represent objects in the problem domain

18
may consider implementing events as a class is in cases where we want to record the events
during operation of the system.

In reason 6 we indicate that it is better to implement the concept as an attribute of a class. An


example in the cash register project is price. We make price an attribute of the class that
represent items. The key issue is whether the concept is a separate identity or an aspect of a
class. If the concept is a separate identity then in general it becomes a class, otherwise the
concept becomes an attribute of one of the selected classes.

We select as class the following concepts: Sale, Store, Item, Cash register (since in a
programming language it is not possible to have a space in the name, the name of the class
becomes CashRegister), Date, Time, and Account. We follow the convention to start with a
capital letter a concept that will be implemented as a class. The purpose of a Sale object is to
contain information about a sale to a customer. Such an object may contain information about,
for example, the total cost and whether the customer owns a customer card. An object of the
class Store contains, among others, information about the type of products available in the
store. An object of the class Item contains information about the type of product (peanut
butter, carton of milk). An object of the class CashRegister computes the amount of money
the customer has to pay for the products the customer buys and may register all the sales of a
day or a longer period of time. We believe the purpose of the other classes does not need any
further explanation.

We list here the all candidate classes and indicate the reason to reject the word:

customer outside the scope of the system


checkout outside the scope of the system
purchase item synonym of item
cashier is an actor, therefore outside the scope of the system
bar-code number attribute of class Item
item class Item
quantity attribute of item or something else?
cash register class CashRegister
price attribute of class Item
product synonym of item
description attribute of class Item
customer card holder synonym with customer; so, outside scope of the system.
We will implement attribute customer card to indicate
that customer deserves reduced prices
reduced price attribute of class Item
end of sale event or operation
total cost of the purchase attribute of class Sale
change attribute of class Sale
sale class Sale
receipt outside the scope of system: a piece of paper or attribute
of CashRegister when referring to the information
morning outside the scope of system or irrelevant for the software
system
manager is an actor, therefore outside the scope of system

19
system synonym of cash register9
end of the day event or operation
start of the working period event or operation
ID attribute of class Account
password attribute of class Account
payment outside the scope of system; in case we wish to record
payments, this will become a class
store class Store
money outside the scope of system
amount attribute of class Sale
inventory quantity outside the scope of system
day synonym of date
bank outside the scope of the system
end event or operation
date class Date
time class Time
account class Account

We have not decided about quantity yet. Is quantity a concept that deserves to become a
class? We do not believe so. Normally, we use quantity in relation with some other concepts.
Here, we mean with quantity the number of items bought of a certain item. For example, if the
customer buys three jars of peanut butter, the quantity is 3. Is it wise to make quantity an
attribute of the class Item? The purpose of the class Item is that for every type of product
available in the shop we have an object. In this object some information about the type of
product it represents will be stored, like price, description, and bar-code number. Do you
think it to be wise to store in such an object the quantity of the item an arbitrary customer will
buy? The value of this attribute of class Item may change for every customer of the shop. The
value of all other attributes of this object does not depend on the customer. They may change,
such as the price attribute will change every now and then. So, to our opinion, it is better not
to make quantity an attribute of class Item.

We will add a class SalesLineItem to the classes mentioned before and we make quantity an
attribute of this class. For every type of product a customer buys the program creates an object
of the class SalesLineItem and stores in this object the quantity the customer buys of that
product. So, if the customer buys three jars of peanut butter, the program creates one object of
the class SalesLineItem and the program stores the value 3 in the attribute quantity of that
object. If the same customer buys two cartons of milk, the program generates another object
of the class SalesLineItem and the program stores the value 2 in the attribute quantity of that
object. Apart from quantity a SalesLineItem object may have other attributes, like an
indication of the type of product (jar of peanut butter, carton of milk). Later, we will return to
this issue.

All this type of information and the relations among the other objects will be included in a so-
called class diagram. In Section 4.3 we will discuss the UML class diagram and will give the
class diagram of the cash register project.

9
Keep in mind: The class CashRegister delegates tasks to other classes.

20
4.3. The class diagram
A class diagram depicts the so-called static structure of a software system. In a class diagram,
a rectangle represents a class. The name of the class is written inside the rectangle.
Furthermore, lines interconnecting the classes refer to associations. Two classes that
cooperate have an association. In this respect cooperation means that an object of one class
needs information of an object of another class or an object of a class wants an object of
another class to perform an action. In Figure 4-1 you find the class diagram of the cash
register project.

Figure 4-1 Class diagram of Cash register project

Apart from the six classes mentioned before, Store, CashRegister, Sale, Item, SalesLineItem,
and Account, you find in Figure 4-1 the class Authorization. We have implemented this class
to be able to store the list of accounts. The class Authorization has been selected for
implementation reasons only. Frequently, implementation issues require additional classes.
We may detect such additional classes sooner or later. The sooner we discover such additional
classes the better: addition of classes in the class diagram is more difficult than deleting
classes. On the other hand, in this stage of the design we should not pay too much attention to
implementation details.

Do we need the Authorization class? It is possible to store the list of accounts in the Store
class. So, if we decide to store the list of accounts in the class Store then the class
Autorization does not appear in the class diagram and the association becomes between Store
and Account. There are, however, several reasons to keep the class Authorization such as: 1)
decrease the number of responsibilities of the class Store and 2) a class for a list is available in
many programming environments (such as Java), so we may reuse the already existing class
for this purpose. We will discuss responsibilities of a class later, but because there are many
associations with the class Store we expect the class Store will have many of them. In a
programming language, a responsibility means one or more methods. In this example we may
think of methods for adding accounts and deleting accounts. From software engineering
perspective, it is wise to limit the number of responsibilities of a class to two or three.
Therefore, we keep the class Authorization.

21
4.4. Naming the associations and navigability
Normally, an association in a class diagram gets a label and an indication in which direction it
is navigable. The label indicates the relationship between the two classes. Let us consider the
association between the class Store and the class Item. We may express that the Store stocks
Item objects or we may express that Item objects belong to the Store, see, Figure 4-2 for the
two possibilities. To decide which of the options apply, we may raise the question: which
object needs information from the other? Here the Store class needs information about, for
example, the price and bar-code number of the Item. The Item need not even know that it
“belongs to” a Store. Therefore, we select the upper option. The arrow indicates the direction
in which the association is navigable, which means in which direction messages can be sent.
In the given example (upper option) a Store object may send messages to Item objects, for
example to request information about the item.

Figure 4-2 Possible navigations between Store and Item class

With names for the associations and indication of the navigability, the class diagram of the
cash register project becomes as given in Figure 4-3.

In this stage of the design of the system it is a good idea to check whether all classes can be
accessed. This means, we check in the class diagram whether every class has at least one
association with the arrow pointing to it. In Figure 4-3 this is true for all classes except the
CashRegister class. Such a class cannot deliver service to any other class in the software. So,
we might consider deleting the class from our design. We should consider, however, that the
user of the system, in this case the cashier, will communicate with the CashRegister object
through the so-called graphical user interface (for short GUI). So, through that GUI, the
cashier may request for service of the class CashRegister and the cashier may store data.
Therefore, we maintain the class CashRegister in our design.

In general, check in the class diagram for all classes where no arrows points to whether an
actor communicates through a GUI with that class. If there are classes without being of
service to other classes, this is an error in the design. It is either possible to delete the class or
change the navigability of one or more associations. If it is possible in a class diagram to start
at a class and return to the same class following the associations then the class diagram
contains a so-called cycle. The cycles should be removed from the class diagram.

22
consists of

belongs to

consists of
Figure 4-3 Class diagram Cash register project with named associations

4.5. Multiplicities
In this stage of the project, it is useful to think about how many (potentially indefinitely
many) of each object (type) we expect. For example, in the cash register system we expect
one CashRegister object, one Store object, order 20 Account objects, and many many Item
objects. The expected number of objects may be indicated in the class diagram at both end
points of an association. These numbers are called multiplicities. With multiplicities the class
diagram becomes as given in Figure 4-4.
consists of

belongs to

consists of

Figure 4-4 Class diagram of Cash register project with multiplicities

23
Look at the association between Store and Item in Figure 4-4. The number 1 at the left and
above the association indicates that an Item object is connected to 1 Store object. This sounds
reasonable, since we cannot expect that one Item object belongs to two Store objects. In
theory, however, it is possible that an Item object belongs to two Store objects. We will not
elaborate on that situation; the software we will prepare is for one shop.

The multiplicity at the right and above the association between Store and Item is a ‘*’. The
asterisk indicates that one Store object contains several Item objects. We discussed this issue
in the first paragraph of this section. The multiplicity at the top of the association between
Sale and SaleLineItem (1..*) indicates that a Sale object contains at least 1 up to several
SaleLineItem objects. A sale without any product does not make sense and a customer may
buy several types of products. The multiplicity at the left side of the association between
SalesLineItem and Item (0..1) indicates that an Item may be connected to one SalesLineItem
object or it may not be connected to a SalesLineItem object. This expresses that a customer
may buy a product or not.

The multiplicity at the Item side of the association between SalesLineItem and Item is 1. This
expresses that a SalesLineItem object always is connected to one Item object. Readers may
think that we can express the quantity a customer buys of one Item by changing the
multiplicity 1 into the multiplicity 1..*. That is not correct. The multiplicity 1..* means that a
SalesLineItem object may be connected to several Item objects, so one SalesLineItem object
will be connected to, for example, a jar of peanut butter and a carton of milk. That is not
according to our definition of the class SalesLineItem. Another option is to change the
multiplicity at the SalesLineItem side of the association records sale of into *. This means that
there might be more SaleLineItem objects for one Item object. This happens, for example, if
on the receipt two or more entries are present for several jars of peanut butter.

Notice the multiplicity (1) at the Sale side of the association between the CashRegister class
and the Sale class. The multiplicity of 1 indicates that a CashRegister object is connected to
one Sale object. It is important to note that, hopefully for the owner of the supermarket, a
CashRegister object will be connected to more than one Sale object during normal operation
of the software. The CashRegister object, however, will not handle more than one sale at the
same time.

In a class diagram you may encounter other multiplicities than shown in Figure 4-4. For
example, if you know exactly the number (let say 5) then you may use the multiplicity equal
to that number (so 5) e.g. dice in a game of poker. Furthermore, we may also specify a choice
of multiplicities by giving a comma separated list: for example 5, 8..11, 17..*. This indicates
that the multiplicity is exactly 5, every number between 8 and 11, or 17 or more. We do not
expect such a multiplicity occurs frequently in practice.

The concept of multiplicities has also impact on the implementation of the software system.
For example, the Store object is connected to several Item objects. Therefore, we see in the
class diagram a multiplicity indicated by *. The Store class needs to be able to find an Item
object with a certain bar-code number. To be able to do so, the Store class needs a variable
that refers to many Item objects. In the implementation, we may select for that variable an
array or a more advanced data structure such as a vector or list. If the multiplicity is one this
means for the implementation that a simple variable (a variable with one value) can be used.

24
4.6. Some remarks about class diagrams
Associations are navigable in one direction. If class A needs information of class B and class
B needs information of class A then we draw two associations, for each direction one. This
may happen, for example, in a system that records family relations. It makes sense that a
parent needs information about a child and a child needs information about the parent. We can
model that by the class diagram given in Figure 4-5.

Figure 4-5 Associations between Parent and Child

Such a bidirectional association between two classes should preferably be prevented to appear
in class diagrams. In fact a bidirectional association is a cycle. In general, a cycle in a class
diagram is a sign of a design problem. In such a design the decomposition is not correct and
the coupling between the classes is too strong. As a result, a bidirectional association may
generate problems in the implementation of the system.10 Consider combining the two classes
into one class. If, however, each class is a concept on its own such as in the Parent and Child
case, we may keep such a couple of associated classes. The main message is, try to minimize
the number of bidirectional associated classes.

The associations among the classes indicate the coupling among the classes in the software. In
a good design, the coupling among the classes is low. This means, a class has associations
with a relatively small number of classes and there is no class that has associations with many
classes or even all classes. If the coupling is high, the problem is that if one class needs to be
adapted, the change affects the other classes as well. This makes maintenance of the software
difficult. Moreover, a high coupling between the classes makes that such a class cannot be
reused in other projects because a class depends too much on other classes. Sometimes we
end up with a class diagram where there are associations among every class. The coupling in
such a system is high, so it is not a good design. Also possible is that one class has
associations with all other classes. We may call this a spider in the web design; see Figure 4-6
for an example. In the general case this is also not a good design. It may, however, appear in
technological systems where one component controls every other component. With
generalization this may be solved. Generalization will be discussed in Section 4.12.

Sometimes, one prepares a so-called object diagram for a system. In an object diagram objects
appear in stead of classes. One does so to clarify obscure or difficult relationships among
some objects. An object diagram looks similar to a class diagram. Objects are indicated by a
name for the object, followed by a colon, and followed by the name of the class. See Figure
4-7 for an example.

10
In many programming languages (not in Java) one encounters problems with the compilation order. For the
compiler it is necessary to know the details of class Child to be able to compile class Parent and the reverse.
Frequently such a situation is not expressible at all.

25
Garage
BrickLayer Carpenter door
mechanic

Works
foreman

Electician Plumber

Figure 4-6 Poor design: spider in the web class diagram

Figure 4-7 An object

4.7. Attributes
The next step in the design process is identification of the attributes and assigning them to
classes. We have already detected some attributes at the time we selected the classes. Some of
the nouns or other domain concepts were not selected to be implemented as class, rather as
attribute of another class. The attributes are listed in the rectangle for the class. Normally, a
class has one or more operations. These operations are listed in the rectangle too. Therefore,
the rectangle has three parts, see Figure 4-8. We call such a rectangle a class icon. The
standard term in UML is class diagram as well; we use the separate term “class icon” to
distinguish single classes from the diagram depicting the relations.

Figure 4-8 Class icon

In the cash register project we have detected four classes with one or more attributes. In
Figure 4-9 you see the class icons for these four classes. The other classes do not have
attributes yet, so we will not give the class icons here.

26
Item Sale

description : string
customerCard : boolean
barcode : string
amount : double
price : double
change : double
reducedPrice : double

SalesLineItem Account

id : string
quantity : integer
password : string

Figure 4-9 Class icons with attributes of cash register project

We will present some comments on the attributes specified in Figure 4-9. The attributes
become variables in the software program. In the software program, we need to indicate the
type of the variable. Here we use the type string to indicate that we will assign a text to the
variable, integer to indicate that we will assign a whole number to the variable, double to
indicate that a real value (for example 25.95) will be assigned to the variable, and boolean to
indicate that the value of the variable is either true or false. It is allowed to use the type
specifiers of the programming language to be used for the implementation. For example, if the
programming language Java is the language selected for the implementation of the system, we
may use int instead of integer.

In literature about UML one frequently finds the class icons in the class diagrams. See Figure
4-10 for an example. We think that only for a system with a few classes this leads to a clear
class diagram. For larger systems, the class diagram contains too much information.
Therefore, in the class diagram we present the classes without attributes and operations and
we present the class icons with the attributes and operations separated from the class diagram.

In a class diagram associations are depicted with the help of solid arrows. Such an association
means that the class where the arrow of the association starts needs some information from
the class where the arrow is pointing to. It is also possible that the class where the arrow starts
wants that the other class performs an action. In both cases the class calls a method from the
other class. In fact, it is not the class that wants something, in the program an object of the
type of the class will do this. Assume an object of class A request information from an object
of class B or an object of class A calls a method of class B. To do so, object A needs a
reference variable to object B. This implies that class A needs a reference variable of type B.
Since, these reference variables are obvious from the class diagram, we have not listed these
variables in the attribute section of the class. You are free to mention these reference variables
in the class icons if you think that to be clearer. We list those attributes in a later phase of the
design.

27
records sale of
0..1
1
SalesLineItem 1 stocks *
Store Item

quantity : integer 1 1 description : string


barcode : string
price : double
reducedPrice : double
1..*

belongs to
consists of

authorizes 1
1 Authorization

Sale * 1

consists of
registers 1
customerCard : boolean CashRegister
amount : double 1 *
change : double
Account

id : string
password : string

Figure 4-10 Class diagram with some class icons included (just for illustration)

In Figure 4-9 we have listed the noun ID as attribute id. This to make clear that ID is not a
class. Recall that the convention is that class names start with a capital letter. Furthermore, we
have not included space characters in names of attributes. This is in accordance with variable
names in programming languages. To make clear that the variable name starts with a new
part, we have used a capital character where a new word starts. We did that without any
comment already for the names of the classes.

4.8. The class diagram without SalesLineItem


In Section 4.2 we have discussed the issue of introducing the class SalesLineItem. In Figure
4-11 you find the class diagram without the SalesLineItem class. The multiplicity at the Item
side of the association from Sale to Item now is 1..*. This expresses the fact that a customer
may buy several kinds of products. It does not indicate, however, that the customer may buy,
for example, more than one jar of peanut butter.

The problem now is where to put the attribute quantity. In Section 4.2 we already stated that it
is not wise to make quantity an attribute of class Item. In this class design (and in the class
design with SalesLineItem) the class Sale needs a list of Item objects. The simplest
implementation for the list is an array. To store the quantity we could implement a second
array with the same number of elements. If some element of the array with references to
objects of type Item refers to a product a customer buys, we store in the corresponding
element of the second array the number of products the customer buys. This is a possible
solution, however, we do not like that solution. The reason is that both arrays contain strongly

28
related information and we cannot express the relation in the software. Therefore, we have to
pay attention to this in the documentation of the software. If we implement the class
SalesLineItem, the type of the product and the number of products of that type bought are
represented and stored such that the relation between the information is clear from the
software and there is no need to pay further attention to the issue. In general, the better the
software documents the software system the better it is.

consist of

Store 1 stocks * Item 1..*

1 1

belongs to authorizes 1 Authorization

1
* 1
Sale consists of
registers CashRegister
*
1 1
Account

Figure 4-11 Class diagram cash register project without class SalesLineItem

4.9. More attributes


The next step is to detect as many attributes as possible. Now we may ask questions like what
information do we need or want to store in an object. Let us concentrate on the class Sale. In
an object of that class we want to store information about a sale to one customer. We may
think about storing date and time, products and quantities, amount of money paid (for instance
a 50$ bill), the amount of change, and an identification of the cashier of the sale. All Sale
objects will be stored somewhere, most probably in a file on a disk or a database. The
information about the date and time might be useful in case the customer comes to the shop to
complain about the fact that on the receipt an incorrect price has been printed. For now, we
add to Sale the attributes date and time. See Figure 4-12. The attribute saleDate has the type
date and saleTime the type time. These types are frequently standard types available in
programming languages. In Java, Date is implemented as a class and that class includes time
also. So, in the Java implementation, only saleDate will be an attribute.

During the next phases of the design we may encounter new attributes for all classes. If that is
the case, we add them to the icon of the involved class. The next step is to discover operations
a class needs to fulfill all the tasks allocated to the class. We will discuss that topic in Section
4.10.

29
Figure 4-12 New class icon for Sale

4.10. Identification of operations


The operations of a class are the so-called responsibilities of the class. Looking for the verbs
in the system description may help to discover the operations. In Java, operations are
implemented by methods. In this phase, the important question is which operations the class
must have to fulfill the responsibilities.

In the system description we find the following verbs related to the cash register: display
price, display description, compute total cost, display total cost, indicates change, and print
receipt. Therefore, we add to the class icon of the CashRegister class the following
operations: displayPrice, displayDescription, computeTotalCost, displayTotalCost,
displayChange, and printReceipt. Is it a responsibility of the CashRegister class to compute
the change? The answer is no, in fact the change is a property of class Sale, which is also
responsible for computing such an attribute. So, we add the operation computeChange to class
Sale and we make class CashRegister responsible of triggering this operation. The icon for the
CashRegister becomes as presented in Figure4-13. We identify the operations by writing “()”
following the name. Most probably these operations need information to fulfill their tasks.
This information might be provided through so-called parameters. Furthermore, we will add
information about the result type of the operations. Later we will specify the parameters and
return types, see Figure 5-5, now we only list the operations. Up to now we did not identify
attributes for the CashRegister class, so the attribute section of the class diagram is empty.

CashRegister

displayPrice()
displayDescription()
computeTotalCost()
displayTotalCost()
computeChange()
displayChange()
printReceipt()

30
Figure4-13 Class icon of CashRegister with operations, but without parameters and result types

4.11. CRC cards


Now it is time to evaluate the class diagram and the decisions we have taken. In this
evaluation process, so-called Class-Responsibility-Collaborators-Cards, CRC cards for short,
may help. The CRC cards are not part of UML. It is, however, a useful tool to evaluate the
design of the software system. We prepare for each class in the system a card. On that card we
write the responsibilities of the class. The responsibilities of the class are in fact the service
we expect from the class. Describe the responsibilities at a high level of abstraction; so, do not
give too much detail. It is possible that a class in the program needs more than one operation
to fulfill one responsibility; so there is not always a one-to-one relationship between the
responsibilities of a class and the operations available in the class. Furthermore, list on the
card the collaborators. Collaborators are classes the class needs to fulfill the responsibilities.
So, collaborators of class A are all classes that perform actions for class A (class A request
that class to perform one or more operations) or all classes that store information class A
needs. If the class diagram of the system at hand is correct, there is an association between
collaborating classes and the association is navigable in the direction of the collaborating
classes. Since we may use the CRC cards to determine the collaborators, we may use the CRC
cards to check the class diagram of the system. We can check whether we have the correct
associations and the associations are navigable in the correct direction. To be able to check
the correctness of the class diagram, it is wise to develop the CRC cards independently from
the class diagram.

In the past one used so-called index cards to record responsibilities and collaborators. In this
document, we will display CRC cards with the help of a table. See for the CRC cards of the
cash register project,
Figure 4-14, Figure 4-15, Figure 4-16, Figure 4-17, Figure 4-18, Figure 4-19, and Figure 4-20.
If no responsibilities are listed on the card then the class does not have a responsibility and if
no collaborators are listed, the class does not need any other class to perform the tasks.

CashRegister
Responsibilities Collaborators
Process sale Sale
Compute total cost Store

Figure 4-14 CRC card for class CashRegister

Item
Responsibilities Collaborators
Stores description and price

Figure 4-15 CRC card for the class Item

Sale
Responsibilities Collaborators
Register sale of one customer SalesLineItem

31
Figure 4-16 CRC card for class Sale

Store
Responsibilities Collaborators
Register sales Item
Gives access to authorization Authorization
management

Figure 4-17 CRC card for class Store

SalesLineItem
Responsibilities Collaborators
Handles price and description of Item
an item
Registers quantity of an item

Figure 4-18 CRC card for class SalesLineItem

Authorization
Responsibilities Collaborators
Manage users Account

Figure 4-19 CRC card for class Authorization

Account
Responsibilities Collaborators
Stores ID and password of one
user
Figure 4-20 CRC card for class Account

Based on the class diagram we may detect errors in the design we have developed, such as:
1. A class does not have any responsibility. This is a rather strange situation. First, make
sure you have not forgotten any responsibility. We may consider removing a class
without responsibilities. We may do that by making the class an attribute of another
class. This is possible because a class without responsibilities does not include
operations. If a class without responsibilities, however, has a number of attributes that
are strongly related, these attributes so to speak form one concept, you may keep the
class. In practice these attributes will be encapsulated, the responsibility of such a
class is to maintain and give access to the encapsulated data.
2. A class has too many responsibilities. In an ideal design there is a balanced division of
responsibilities over all available classes and a class has three to four responsibilities
maximum. This may seldom be feasible. A design, however, with one class with the
majority of the responsibilities and the other classes none or one responsibility is not a
good design. We may improve a design that includes a class with too many
responsibilities by creating one or more additional classes and divide the

32
responsibilities over the new classes and the original class. Another solution is to give
another class one or more responsibilities from the class with too many
responsibilities. It is also possible that the responsibilities of a class are described on a
too low level of abstraction. If that is the case, it is better to combine the
responsibilities to achieve a higher level of abstraction.
3. When class A is collaborator of class B and class B is collaborator of class A then try
to combine the two classes into one class. We could have detected this error already in
the class diagram because in that case we have associations navigable in two
directions between the two classes. As already said, in special situations we may
accept this situation.

The ultimate test with the help of CRC cards is to review how the class model fulfills the
required functionality. This can be accomplished by role-playing. Some team members realize
in words some responsibilities and one tries to realize the so-called scenarios of all use cases.
Each team member receives the index cards of one or more classes. A scenario is a possible
interaction between the system and some actors. An example scenario is: a customer arrives at
the checkout to pay various purchase items, the customer pays with a certain amount of
money, and the cashier gives the change. Here we have described the scenario in a generic
way, because a scenario with a customer that arrives with seven products to pay differs from a
scenario with a customer with eight products to pay. Furthermore, customers that buy the
same products in different quantities form different scenarios. We prefer to describe the
scenarios in a generic way, because for testing the design it does not matter how many
products and in what quantities a customer buys. A different scenario, however, is that the
cashier does not have change or the customer has not enough money to pay.

During this test, we discover whether the classes have the responsibilities to fulfill the tasks,
the classes have the correct collaborators, and the navigability of the associations in the class
diagram is correct. Normally we will not check all possible scenarios. We will start with a
characteristic scenario and take the scenarios where the operation will differ. So, in the cash
register project, we start with a customer that buys some products, has enough money to pay,
and the cashier is able to give change. We test also the scenario where the customer does not
have enough money to pay and we test the scenario where the cashier is not able to give
change. In the cash register project we may also test the scenario where a customer card
holder arrives at the checkout. The challenge is to think of scenarios that are not handled
correctly by the designed system.

After testing several scenarios, we adapt the class diagram if needed. We did our best to make
the class diagram correct. Furthermore, the cash register project is a relatively simple project.
Therefore, it is not a surprise that we do not discover errors in the prepared class diagram. So,
there is no need to adapt the class diagram given in Figure 4-4.

In the next chapter we will deal with sequence and communication diagrams. Role-playing as
described above is valuable for deriving and testing these diagrams as well. With the help of
these diagrams it is possible to validate the class diagram and discover additional attributes
and methods for classes. But first we will discuss the important concepts generalization and
polymorphism.

33
4.12. Generalization
Some classes in the project may have many concepts in common. We may think of concepts
like attributes and, more important, operations. If some classes have much in common, we
may think about a generalization of the classes and we may introduce a so-called generalized
class. In the cash register project we do not encounter such classes; therefore, we will
illustrate the issue with the help of another example. See Figure 4-21 for a part of a class
diagram. We show only the part of the class diagram that is important for explaining the issue.

Day

1 1 1
contains contains

contains
0..1 0..1 0..1

Dinner Lunch Breakfast

1 1 1 1
has eater

0..*
has eater 0..*
0..* has eater
has cook 0..1 Person

Figure 4-21 Class diagram to detect generalization

In Figure 4-21, the classes Dinner, Lunch, and Breakfast have the associations “contains” and
“has eater.” The class Dinner has an additional association “has cook.” Furthermore, the
multiplicities of the associations and the navigability of the associations are the same. So, we
may expect that a generalization of the classes Dinner, Lunch, and Breakfast is possible. A
potential name for the generalization is Meal.

Searching for strongly related nouns in the system description of the project is another way to
discover generalization. If we consider, for example, the nouns dinner, lunch, and breakfast,
we conclude that meal is a more general concept of dinner, lunch, and breakfast. So, there are
two reasons to consider introducing a new class Meal containing the common parts of the
classes Dinner, Lunch, and Breakfast. Meal is called a generalization of Dinner, Lunch, and
Breakfast and Dinner, Lunch, and Breakfast are called specializations of Meal. With
generalization the class diagram becomes as given in Figure 4-22.

The UML symbol to indicate generalization in a class diagram is a solid arrow with a hollow
triangle head. The arrow start at the specialized classes and points to the generalized class,
here Meal, see Figure 4-22 for an example. The associations that Dinner and Person, Lunch
and Person, and Breakfast and Person have in common in Figure 4-21 (has eater) now are
between the classes Meal and Person. The same holds for the association between Day and

34
Dinner, Day and Lunch, and Day and Breakfast (contains). The association between Dinner
and Person (has cook) is still present, since that association is typical for class Dinner.

contains

Figure 4-22 Class diagram with generalization

The class Meal contains the common part of the classes Dinner, Lunch, and Breakfast. The
common part contains attributes and operations. The classes Dinner, Lunch, and Breakfast
may contain additional attributes and methods. To be precise, these attributes and operations
are not present in all of the three mentioned classes. So, in that respect the classes Dinner,
Lunch, and Breakfast differ. In programming languages, generalization is implemented
through inheritance. In a programming language, we say that, for example, the class Dinner
inherits attributes and methods (implementation of the operations) from class Meal. Note that
inheritance is from Meal to Dinner, Lunch, and Breakfast which is opposed to the direction of
the arrow used to indicate generalization.

In Figure 4-6 we depicted a design with one class associated with all other classes in the class
diagram. There we called this a spider-in-the-web design. In Figure 4-23 we show a class
diagram of the same system without this problem. In this design we have created a
generalized class Subcontractor for all craftsmen involved in this system. In this design, the
class Worksforeman is only associated with the new class Subcontractor.

Generalization or inheritance has advantages and disadvantages. On the positive side we may
mention that the class diagram becomes clearer because, for example, the number of
associations decreases. More important is that programming of a project needs less time,
because it is not necessary to repeat coding methods and attributes. On the negative side it is
important to note that a generalized class and specialized classes have a high coupling. The
result is that if there is a need to change something in the generalized class, most probably the

35
specialized classes need a change as well. Therefore, it is wise to use generalization only in
cases where there is a conceptual relationship between the classes.

Figure 4-23 Spider in the web design resolved through generalization

Before, we have used the terms generalized and specialized class. In literature we find also the
terms superclass for the generalized class and subclass for the specialized class. So, a subclass
is a specialization of a superclass. The term superclass may be misleading. In fact, the
subclass includes all attributes and operations from the superclass and has attributes and
operations of its own. Therefore, the subclass is more powerful than the superclass. The
super/sub terminology has to do with the generalization hierarchy. The superclass is higher in
the hierarchy than a subclass.

In this section, we have shown a generalization hierarchy of two levels. Later in this chapter
we will show a generalization hierarchy of three levels. In programming, the generalization
hierarchy is not limited to two or three levels.

In programming languages, generalization is implemented through inheritance. Classes


Dinner, Lunch, and Breakfast inherit methods (implementation of the operations) from class
Meal. If the behaviour of these methods does not differ for classes Dinner, Lunch, and
Breakfast they share the same instructions. Then the instructions of these methods are not
repeated in the code for the subclass. In some situations the behaviour of the subclasses may
differ. If that is the case then the methods need to be redefined in the subclass. In
programming languages this concept is known as polymorphism. Later, we will discuss
polymorphism in more detail.

36
4.13. Generalization versus composition
In the previous section we have discussed generalization and we mentioned that
generalization is implemented through inheritance. The class Meal contains several attributes
and operations. The classes Dinner, Lunch, and Breakfast inherit all these attributes and
operations. Apart from the attributes and operations, for example, class Dinner inherits from
class Meal, class Dinner may contain a set of attributes and operations. Through inheritance
we compose, so to speak, a class from class Meal and class Dinner. There is another way to
build a class from several classes and that is called composition. An example of composition
is given in Figure 4-24 where you find class icons for the classes Point and Quadrilateral. The
icons are far from complete, the purpose is only illustration of the concept. The class Point
defines a point in the two dimensional space and class Quadrilateral uses the class Point to
define the vertices of the quadrilateral. Class Quadrilateral is composed of four Point objects.
The attributes vertex1, vertex2, vertex3, and vertex4 refer to these objects.

Figure 4-24 Class composition

The conclusion is that we may assemble classes in two ways: generalization or inheritance on
the one hand and composition on the other. The question now is in which situation we apply
which method. For that purpose we can use the test “is a” and “has a.” If the test “is a” is true
then we apply generalization or inheritance and if the test “has a” is true we apply
composition. For example, “dinner is a meal”, therefore we apply generalization or
inheritance. On the other hand “a quadrilateral has a vertex” is true, therefore we apply
composition. The “is a”-test, however, sometimes is misleading. Consider for instance the
following sentence: “a sheepdog is a breed” does not express a generalization. If you are in
doubt you may try the sentence “every sheepdog is a breed” which is not true. On the other
hand, the sentence “a sheepdog is an animal” is a generalization.

We conclude this section with comment on the class Quadrilateral. We could think of defining
the class Quadrilateral given in Figure 4-24 without using the class Point. Every vertex will
then be defined by two variables of type double. It is, however, a better idea to use concepts
we defined before and thus, define the class Quadrilateral with the class Point as we did in
Figure 4-24.

4.14. Polymorphism
In this section we will elaborate on the concept polymorphism. We do that based on an
example. Assume we design software to draw two-dimensional pictures consisting of
elements like circle, triangle, or rectangle. The user of the software is able to interactively
select the elements and compose the picture. The software contains classes for each element:

37
class Circle, Triangle, and Rectangle. Furthermore, the software needs operations to draw the
elements. Where do we specify the operations draw? If we follow the object-oriented
programming paradigm, we will let every element have an operation draw. Every element, so
to speak, draws itself.

In the software we need a method that draws the composed picture. This method needs among
others a so-called data structure to store the selected elements. We will not discuss the data
structure, but you may think about an array. A sketch of the method to draw the figure might
be as given in Figure 4-25.

for all elements do


{
type of element is:
when triangle: call method to draw a triangle
when circle: call method to draw a circle
when rectangle: call method to draw rectangle
}

Figure 4-25 Sketch of method to draw figures

The idea of the code given in Figure 4-25 is that the software goes through the array of
elements and tests the type of each element and calls the method draw defined in the class of
the type of the element. So, for example, if the element is a circle, the method draw of the
class Circle is called. Because the software needs to check the type of element, the classes for
each element need an attribute to indicate the type of the element. This is a workable set up,
but with inheritance we can do better.

Assume we introduce a generalized class Shape. All attributes and operations common to the
classes will be defined in this class. The classes Circle, Triangle, and Rectangle inherit the
common parts from the class Shape. See the class diagram given in Figure 4-26 where we
have not included unimportant details.

38
Figure 4-26 Class diagram with inheritance

In the remainder part of this section we will discuss some implementation details. In Figure
4-26 you see that the classes Circle, Triangle, and Rectangle have an operation draw.
Furthermore, class Shape has an operation draw as well. The method draw in the
implementation of class Shape will not include instructions to draw a Shape; the body of draw
is empty. Including code does not make sense, since we can only draw an element if we know
what type it is. One step further is to make the method draw in Shape a so-called abstract
method. An abstract method has no body at all, but instead classes that inherit from Shape
will have a method draw with instructions to effectively draw that element. Since the class
Shape contains an abstract method, we call the class Shape an abstract class. This indicates
that we never will create an object of class Shape. We do, however, create objects from class
Circle, Triangle, or Rectangle and because of the inheritance, the common type of these
objects is Shape. With classes according to the design given in Figure 4-26 the method to
draw a picture becomes as given in Figure 4-27.

for all elements elem do


{
elem.draw()
}

Figure 4-27 Method to draw a figure

In Figure 4-27 the variable elem will refer to an object of class Circle, Triangle, or Rectangle.
We will discuss the declaration of the variable elem later. If the variable elem refers to a
Circle object, the method draw of class Circle is called. If the variable elem refers to a
Triangle object, the method draw of class Triangle is called and if the variable elem refers to a
Rectangle object, the method draw of the class Rectangle is called. This means, the method

39
draw in Figure 4-27 sometimes is the method draw of class Circle, Triangle, or Rectangle and,
therefore, we call the method draw polymorph.11

One of the reasons for programming according the object-oriented paradigm is to reuse parts
of software without the need for adapting existing code. Inheritance and polymorphism
contribute to this. To illustrate that, assume the program to draw two-dimensional pictures is
ready and you want to add the possibility to include ellipses in the pictures. We have to define
a class Ellipse, but to do that it is not necessary to change the definitions of the classes Circle,
Triangle, and Rectangle. If we had selected to implement this drawing software without using
inheritance, we had to adapt the method to draw a picture given in Figure 4-25. We have to
add to the definition a line “when ellipse: call method to draw an ellipse.” The software had to
be recompiled and then we can use the new software.

No change in the existing software and even no recompilation of existing software are needed
if we use inheritance and polymorphism to implement the software. The only thing we have to
do is defining the class Ellipse and define the method draw for this class. The class Ellipse has
to be compiled and loaded together with the compiled part of the existing software and the
software works! So, polymorphism makes it easy to add functionality to an existing program
and makes reuse of software simple.

Now we return to the definition of the variable elem and the variable where we store all
elements the picture is composed of. Assume we will store the elements that are part of the
picture in an array with the name “elements.” To what type of object the variable elements
will refer? To Circle objects, to Triangle objects, to Rectangle objects, or to Ellipse objects? It
will refer to any of them. In the array declaration we have to specify to which type of object
the variable elements will refer. It is, however, impossible to declare a variable to refer to
more than one type of object. So, how can we solve this problem? Think about what objects
of class Circle, Triangle, Rectangle, and Ellipse have in common. All inherit from class
Shape. Therefore, an object of class Circle is also an object of class Shape and that holds also
for Triangle, Rectangle, and Ellipse. So we define the variable elements as follows:

private Shape [] elements;

The variable elem also refers to objects of class Shape, so the definition of elem is:

private Shape elem;

11
Polymorph means having many shapes. In this case the method draw has many shapes.

40
5. Interaction diagrams
The class diagram models the static structure of a system. In an interaction diagram we model
dynamic behavior of a system. If needed to clarify some difficulties, we may prepare several
interaction diagrams. In general we depict one scenario in one interaction diagram. Recall
what a scenario is: A scenario is a possible interaction between the system and some actor(s).
An example scenario is: a customer arrives at the checkout to pay a jar of peanut butter, two
cartons of milk, and one loaf of bread, the customer pays with a banknote of €20, and the
cashier gives the change. Another scenario is the customer that pays for a jar of marmalade
and one carton of milk with a banknote of €10. We will prepare at least one interaction
diagram for a typical scenario. Moreover, we will prepare interaction diagrams for the more
complex scenarios and for scenarios where it is not quite clear what happens in that scenario,
how to implement in the software, or both. Therefore, it might be more interesting to prepare
an interaction diagram for the situation where the customer is unable to pay for the purchase
items or the cashier is not able to return change.

In an interaction diagram, the flow of messages is depicted. Therefore, this is a means to


detect operations for the classes. UML knows two types of interaction diagrams: sequence
diagram and communication diagram. In a sequence diagram the emphasis is on the order in
which the messages occur and in the communication diagram the emphasis is on the relation
among the objects. In fact both diagrams contain the same information and it is rather simple
to translate a sequence diagram into a communication diagram and reverse.

5.1. Sequence diagram


The purpose of the sequence diagram given in Figure 5-1 is to illustrate the notation and
symbols used in such a diagram. Although we have used partly the same names as in the
sequence diagram for the cash register project, this sequence diagram has no relation to the
project. In Section 5.2, we present a sequence diagram related to the cash register project. In
the top left corner of Figure 5-1, you see an actor. This is the actor that initiates the use case
we represent with the sequence diagram at hand. The name of the actor, here Cashier, is
written below the actor. To the right of the actor you see the symbol for a class. This time,
however, it is not a class. It is an object. In principle objects play a role in a scenario,
therefore, we depict objects in a sequence diagram. A class and an object are indicated with
the same symbol, a rectangle, they differ by the colon. Here, “:CashRegister” means that the
rectangle represents an anonymous object of the type CashRegister. If we want to indicate a
name for the object, we write “name:CashRegister” in the rectangle. In Figure 5-1 you see an
object of the class Sale. This object is not at the top level indicating that the object is not
present at the time the scenario starts. The convention is that all objects that are available at
the time of the scenario, are at the top level, like the CashRegister type object here. The
creation of the Sale type object is also explicitly depicted in the sequence diagram by the solid
arrow with the text new Sale(). Notice the open head of the arrow. In Java, new Sale() is the
object creator (in Java constructor) for a Sale object.

41
Starting from the actor and objects there is a dashed line downwards. This is the so-called life
line. The actor or object where the dashed line originates stays present in the program until the
line stops. The lifeline of the object of type Sale is shorter than the lifeline of the object
CashRegister. This shows that the object Sale lives shorter than the CashRegister object.
Objects are not active during their complete life. Active means that the object is executing a
method or is waiting for a reaction of a message sent to another object. If an object is active
you see a rectangle that hides the lifeline of the object. If object A sends a message to object
B this means that object A calls a method of object B. In Figure 5-1 you see, for example, that
the CashRegister object sends the message “findItem(barcode)” to the Sale object. The Sale
object executes the method findItem. The method findItem finds the object of type Item that
has the bar code given as argument.

:Cash-
Register

Cashier
start new Sale()
:Sale

barcode +
quantity findItem(barcode)

item

destroy()
receipt

Figure 5-1 Symbols in a sequence diagram (not part of the ongoing example)

If the Sale object has been able to detect the Item object of the product the customer wants to
pay for, the Sale object sends back to the CashRegister object a reference to the Item object. If
the method returns some information we indicate that by a dashed arrow and label the arrow.
Here the label is item. This arrow is optional if no information is sent back.

In general, there is a so-called Graphical User Interface (GUI) between the actor and the
program. Such a GUI will not be depicted explicitly in a sequence diagram. We, however,
indicate that some information will be sent from the Cashier to the CashRegister object by
solid arrows, such as the arrows labeled with start and barcode+quantity. If some information
will return to the actor, we use dashed arrows with a label, see for example receipt in Figure
5-1.

Sometimes an object will not live until the scenario comes to an end. One of the objects then
will send a message to destroy the object to the object to be destroyed. Nevertheless, this is

42
not anymore true in Java. In fact, in Java the so called “garbage collector” is responsible for
discovering and destroying objects when they are not needed anymore and an explicitly
destroy message is never sent. We indicate the end of the life of an object with the help of a
cross. See, for an example, the lower right corner in Figure 5-1.

Frequently it is necessary to use a return value of a message in another message. For example,
we may use the variable item used in Figure 5-1 as label of the dashed arrow from Sale to
CashRegister. In some books we see in such cases a label item = findItem(barcode) to make
more explicitly that the variable item12 is the result of the message findItem(barcode).

5.2. A sequence diagram for the cash register project


In Figure 5-2 we present a sequence diagram for the following scenario. A customer, no
customer card holder, comes to the checkout with one product to buy. The bar code of the
product is known and can be read by the bar-code reader. The customer has enough money to
pay and the cashier has change available.

It is possible to model a scenario in a specific way or in a general way. A specific scenario is,
for example, that the customer buys one jar of peanut butter. Then the bar code of a jar of
peanut butter and 1 will be specified as label in the sequence diagram. Also the bar code of a
jar of peanut butter will be given as argument with the call of the method findItem. Suppose
the bar code of a jar of peanut butter is 97812176. Then we specify in the sequence diagram
findItem(97812176) and find(97812176). In general, it does not make sense to be so specific
in a sequence diagram. Therefore, we give the bar code a name and then the sequence
diagram can be used for every product.

In Figure 5-2, the objects “:CashRegister”, “:Item”, and “theStore:Store” are present at the
start of the scenario depicted by this sequence diagram. The scenario starts with the arrival of
a customer who wants to pay for the only product. The software cannot detect the arrival of
the customer. So, some information should go to the software system. We depicted this with
the solid arrow with the label start. Most probably, the signal to the system is the bar code of
the first product the cashier scans. We have modeled this as a separate signal, but an
alternative is that scanning of the first bar code starts the scenario. The cash register now
responds by creating an object of type Sale. To do so, the cash register object sends the
message “new Sale()” to the class Sale and this class creates an object.

12
One remark: item is a good indication what the result is of the message, however, item is not a good name in
the software. It is not good practice to have entities in the program that only differ in case of the letters. Recall,
we have already a class Item. Introducing the variable item that refers to a specific Item object is not a good idea.
The name itemRef, for example, is a better name.

43
:Cash- theStore
:Item
Register :Store
Cashier
start new Sale() theSale
:Sale
barcode +
quantity
find(barcode)
item

new SalesLineItem
makeLineItem(item,quantity) (item, quantity) lineX
:Sales-
LineItem

code (findItem(barcode)) to the Store object.

44
lineX
getPrice(lineX) getPrice() getPrice()

price price price

getDescription(lineX) getDescription() getDescription()


description description description

Figure 5-2 Sequence diagram of cash register project


computeSubTotal()

endOfSale
+ money computeChange(subTotal,money)
change
getReceipt()
change + receipt
receipt

In Figure 5-2 the CashRegister object sends the message to find the product with a certain bar
The next action of the CashRegister object is to initiate generation of a SalesLineItem object.
The CashRegister object may be responsible for that action. We, however, have made the Sale
class responsible for creating the SalesLineItem object. The Sale object needs to know a
reference to the SalesLineItem object and the CashRegister object does not need that
information. To initiate creation of a SalesLineItem object the CashRegister object sends the
message makeLineItem(item, quantity). This message sends the reference to the Item object
(in this case the jar of peanut butter) and the quantity (here 1). The Sale object sends the same
information (item and quantity) with the creation message to SalesLineItem (new
SalesLineItem(item,quantity)). The SalesLineItem object returns a reference to itself to the
Sale object which is not explicitly indicated in Figure 5-2. The Sale object returns a ready
signal to the CashRegister object. Such a ready signal, normally, will not be labeled in a
sequence diagram.

We now want to display on the cash register a description of the item the customer buys (here
jar of peanut butter) and the price of the item. The Item object has that information. So, some
object needs to request the Item object about this information. The CashRegister initiates this
process by explicitly asking information about the newly created object lineX of class
SalesLineItem to theSale object of class Sale. Sale has a reference to lineX : SalesLineItem
and therefore sends a message to it in order to retrieve information about the Item object
associated with it. In Figure 5-2 you can see the sequence of messages --- getPrice and
getDescription --- discussed.

Look at the message computeSubTotal(). The CashRegister class is responsible for computing
the subtotal of the products the customer wants to buy. To express such a situation we can
draw a solid arrow to the CashRegister object itself. An alternative is to make the Sale class
responsible for computing the subtotal. The Sale object, however, needs to know the total
amount of money involved with the sale at hand, the subtotal is not important. Therefore, we
made the CashRegister responsible for computing the subtotal.

In Figure 5-2 we have depicted a scenario for a customer that buys one item of a certain
product. A sequence diagram for the scenario for a customer that buys several items is not
more complex. To depict such a situation in a sequence diagram, we have to repeat the part
from the signal “barcode + quantity” until and including the call of the method
computeSubTotal. The simplest solution is to repeat that part of the sequence diagram,
however, UML has more advanced notation available to handle repetition. The more
advanced features are not part of this course.

5.3. Searching the Item object


In the sequence diagram given in Figure 5-2 we did not specify in which way the
CashRegister object is able to find the Item object with a specified bar code. If we want to
give the details about the search process we can model it as given in Figure 5-3. In this
sequence diagram only three products are represented: carton of milk, jar of marmalade, and
jar of peanut butter. We expect that you can imagine what the sequence diagram looks like for
a real supermarket with thousand or more products. In the next paragraph we will elaborate
somewhat more on that issue. The idea of this sequence diagram is that the Store class has the
operation find that subsequently asks the Item objects available in the shop what the bar code
is. Then the operation checks whether the bar code is the same as the bar code given in the
argument. This operation continues to do that until the bar code given as argument is found.
The result of the operation find is a reference to the Item representing the jar of peanut butter.

45
In Figure 5-3 we have modeled every object explicitly. If many objects are involved this is not
a reasonable approach. We can also represent all objects with one rectangle. In such a
sequence diagram, we only mention “:Item” and the rectangle represents different objects. It
is possible to indicate that a message has to be repeated. If we apply repetition and we
represent all products with one Item object, the sequence diagram may become as given in
Figure 5-4. The simplest repetition is to specify an asterisk meaning the message has to be
sent several times. If we specify a number, say ten, then the meaning is that the message has
to be sent ten times. In this specific case, we have to send the message as long as the Item
object with the given bar code has not been found. Such repetitions can be formulated as well;
however, we think these options are for more advanced users.

5.4. Relation with the class diagram


Normally we will develop a sequence diagram for more scenarios; however the number of
sequence diagrams is limited. If we are ready with the sequence diagrams, it is time to check
whether the associations given in the class diagram correspond with the message calls in the
sequence diagram. Furthermore, most probably we have detected some operations, attributes,
or both we have not detected before and, therefore, we have to update the class icons. Another
possibility is that we have detected additional classes. First we will look whether the sequence
and class diagram correspond.

For example, look at the message find(barcode) the CashRegister object sends to the Store
object. This message implies that in the class diagram there is an association between the
class CashRegister and the class Store. Furthermore, the association should be navigable in
the direction of Store. In the class diagram of Figure 4-4 the association is present and the
navigability is correct. It is wise to check the other associations as well.

Now we discuss the changes in the class icons. First we do that for the class CashRegister. In
the sequence diagram, we see that the CashRegister sends messages to the Sale object. The
CashRegister needs a reference variable to the Sale object to be able to send the messages. We
call this variable refSale. When a new sale is initiated, this variable will point at the new Sale
object that is created. The CashRegister class needs a variable refStore in which the reference
to the Store object is saved. Furthermore, we detect the operation computeSubTotal in the
CashRegister class. Before, we have detected the operation computeTotalCost. If we compute
the so-called running sum with the help of the operation computeSubTotal we do not need the
operation computeTotalCost, the subtotal computed for the last product with
computeSubTotal is the total amount the customer has to pay. Therefore, we delete the
operation computeTotalCost from CashRegister class icon and add computeSubTotal to the
class icon. See Figure 5-5 for the adapted CashRegister class icon.

From now on we indicate in the class icons the return types of operations and the type of the
parameters. For example, we indicate that the return type of the operation displayPrice is
double. Conceptually this is correct; a price can have a fractional part. In the graphical user
interface, however, such a value will be implemented as a string. Furthermore, we put a plus
or minus sign before the attributes and operations. Later we will explain the meaning of these
signs.

46
marmelade peanutButter
:Store milk:Item
:Item :Item

:CashRegister

find(97812176)
getBarCode()

11559738

getBarCode()

23467954

getBarCode()

97812176

peanutButter

Figure 5-3 Searching for peanut butter

47
Figure 5-4 Searching for peanut butter with multiplication

A class may require a constructor to initialize objects. In general we will not mention the
constructors in the class icons. If we detect constructors with parameters, it makes sense to
mention them in the class icon. In this case the Sale object has no parameters so we do not
show its constructor. From the sequence diagram (Figure 5-2) we detect the following
operations: finditem, makeLineItem, getPrice, getDescription, computeChange, and
getReceipt. The class Item needs the methods getPrice and getDescription. The class
SalesLineItem needs the methods getPrice and getDescription. This class needs an object
generator method with two parameters indicating the product the customer buys and the
quantity. Moreover, it seems useful to store the reference to the Item object in this object, so
the class needs a variable theItem.

Java, like many other object-oriented programming languages, provides means to protect
attributes and methods from outside use. In Java attributes and methods may be declared to be
private, public, or protected. Private means that the attribute or method cannot be accessed
from another object. A public attribute or method can be accessed by any object. It is good
practice to define attributes as private. In general, methods are public, especially those we
detected during UML design. Protected attributes and operations play a role with inheritance,
for the rest they behave like private ones. In the design phase of the system it is possible to
indicate whether attributes and methods can be used from outside the object itself or not. For
private attributes and operations we put a minus sign before the name in the class icon, for
public attributes and operations we put a plus sign before the name, and for protected
attributes and operations we put #. From now on, we will do that in the class icons. The
operation computeSubTotal is only of service to the CashRegister class. No other objects will
call this method. Therefore, we have declared this method as private.

48
As stated in the previous paragraph, it is good practice to define attributes of classes to be
private. This means, it is impossible to set and get the values of the attributes directly. To
make it possible to change private attributes we need a so-called setter method. Setters may
perform additional checks. When a setter is absent the attribute is read-only. To read the value
of a private attribute we need a so-called getter method. For example, we may expect that the
class SalesLineItem has a method getQuantity which returns the value of the quantity the
customer buys the product. See Figure 5-5 for the updated class icons.

CashRegister Sale

- refSale : Sale
- customerCard: boolean
- theStore : Store
- amount: double
- change: double
+ displayPrice()
- saleDate : date
+ displayDescription()
- saleTime : time
- computeSubTotal()
- refStore : Store
+ displayTotalCost()
+ computeChange()
+ displayChange()
+ printReceipt() + Sale(refStore:Store)
+ makeLineItem(quantity:integer, item:Item)
+ getPrice(item : SalesLineItem) : double
+ getDescription(item : SalesLineItem) : string
Item + computeChange() : double
+ getReceipt() : string
- description : string
- barcode : string
- price : double
- reducedPrice : double SalesLineItem

+ getPrice()
+ getDescription() : string
- quantity : integer
+ getReducedPrice() : double
- theItem : Item

Store + SalesLineItem(it:Item,qu:integer)
+ setItem(it:Item, quantity:integer)
+ getPrice() : double
+ getDescription() : string
+ find(barcode:string) : Item + getQuantity() : integer

Figure 5-5 Adapted class icons of the cash register project

In case we prepare sequence diagrams for other scenarios we may encounter additional
attributes and operations. For example, we may detect methods related to handling card
holders. In the cash register project that is not the case, so we may start to think about

49
implementing the software. Before, we can do so, we have to think about separating the GUI
and the engine.

5.5. Separation of GUI and engine


In Figure 5-2 we did not model the interface between the cashier and the software. We have
indicated the signals by start, barcode+quantity, endOfSale, money, and change+receipt.
If we want to model the Graphical User Interface explicitly and we want to separate the
responsibilities, we have to split the CashRegister class into a class CashRegisterGUI and a
class CashRegisterEngine. Signals, like start, become operations in the engine. The class icon
of the CashRegisterEngine becomes as depicted in Figure 5-6. You see that we have added to
the operations: setBarcodeAndQuantity, enterMoney, start, and endOfSale.

CashRegisterEngine

- refSale : Sale
- theStore : Store

+ displayPrice() : double
+ displayDescription() : string
- computeSubTotal() : double
+ displayTotalCost() : double
+ computeChange() : double
+ displayChange() : double
+ printReceipt() : string
+ setBarcodeAndQuantity(barcode:string,quant:integer)
+ enterMoney(money:string)
+ start()
+endOfSale()

Figure 5-6 Class icon of CashRegisterEngine13

5.6. Communication diagram


In a communication diagram, like in a sequence diagram, we depict the flow of messages. In
the communication diagram the emphasis is the relation among the objects. Because the class
diagram and communication diagram are similar, it is easier to check the consistency of both
diagrams. The communication diagram corresponding to Figure 5-2 is given in Figure 5-7.
This communication diagram contains the same information as the sequence diagram in
Figure 5-2. In a sequence diagram the order in which the methods are called is clear. In a
communication diagram, the order in which the methods are called is less important; it is
indicated by numbers. The first message from the cashier gets number 1. This message goes
to the CashRegister object. The message the CashRegister object sends as a result of this
message is the method call new Sale() to the Sale object. This method call gets the number
1.1. The Sale object does not send any messages as a result of this call. The next message the
CashRegister object receives has number 2. The CashRegister sends several messages as a
result of message 2. The first one has the number 2.1, the second 2.2, and so on. The first
13
At this level, the types double and integer mentioned in this icon are strings; this has to do with the
responsibilities of GUI and engine.

50
message the Store object sends as a result of message 2.1 would have the number 2.1.1. There
is, however, no message as a result of the message 2.1. For example, the number 2.3.1
indicates that the method call getPrice() sent from SalesLineItem to an Item object is the
result of the second message from the actor, the third method call from the CashRegister
object, the first message from the Sale object, and the first message from the SalesLineItem
object.

In Figure 5-8 we have depicted the search for a specific product (in this case a jar of peanut
butter). We may depict the search for a specific product in a more general way with the help
of a repetition. See Figure 5-9 for an example. The asterisk before the getBarCode(barcode)
indicates that this message will be sent several times.

Figure 5-7 Communication diagram cash register project corresponding to Figure 5-2

51
2.3.1.1: getPrice()
2.4.1.1: getDescription()

lineX
2.1.3 getBarCode() peanutButter
:SalesLineItem
:Item

2.1.2 getBarCode()
theStore marmelade
:Store :Item
2.2.1: new SalesLIneItem
(item, quantity) 2.1.1 getBarCode()
2.3.1: getPrice() milk
2.4.1: getDescription() :Item

2.1: find(barcode)

2.5: computeSubTotal()

theSale
:CashRegister
:Sale

1: start
1.1: new Sale() 2: barcode + quantity
2.2: makeLineItem(item,quantity) 3: endOfSale + money
2.3: getPrice(lineX)
2.4: getDescription(lineX)
3.1: computeChange(subTotal,money)
3.2: getReceipt()

Cashier

Figure 5-8 Communication diagram cash register project including search for peanut butter

52
Figure 5-9 Communication diagram with search for Item

53
6. Implementing cash register project
The design is almost finished and we may think about implementation issues, like what data
structures we need to implement for example to store all item objects. An important issue here
is, to consider reuse of software components designed and implemented before.

6.1. Reuse of software components


Inexperienced programmers have a tendency to design and implement all software
components by themselves. Frequently, programmers reinvent the wheel. Since software
development is labor intensive and labor costs are high, developing software is expensive.
Therefore, one aspect is reuse of code from other projects or other parts in the same project;
that aspect needs special attention. Another aspect is use of library code; that is common
practice. For example, nobody writes their own GUI components.

In the cash register project we may reuse parts for the graphical user interface and we may use
classes for date and time.

6.2. Data structures needed for the cash register project


The class Store needs a data structure to store Item objects for all available products. For this
purpose we may select an array. In UML, the declaration becomes: items: Item[]; the
equivalent declaration in Java is Item[] items;. The size of the array is fixed, so it is
difficult to adapt the software if the range of products of the supermarket changes. The Java
library has standard implementations of flexible lists (appropriately known as type List). A
list can grow and shrink in size as needed. Furthermore, the list classes14 contains methods to
insert or remove elements in between. The declaration in Java then would become
java.util.List items; (the part java.util. can be left out when a proper import
statement is used at the start of the Java file). For the time being the array will do, so we will
postpone implementation of advanced data structures for the cash register project.

To be able to prepare a receipt the object Sale needs a data structure. A receipt is in fact a list
of SalesLineItem objects, so we may use one of the data structures described in the previous
paragraph. In the implementation of the cash register project we choose an array for this list as
well. So, we declare: SalesList: SalesLineItem[];.

The class Authorization needs a structure to save accounts for all people that may use the
system. Here we choose also an array: accounts: Account[];. Furthermore, the class
Autorization needs a method to validate a given ID and password:
validate(id:string,password:string): boolean;. And the class Account needs a method that
does the same: validate(id:string,pw:string):boolean;.

14
Actually List is not a class but an interface; different implementations (e.g. Vector, ArrayList,
LinkedList) are classes.

54
To complete the documentation of the software we may add the mentioned variables and
methods in the class icons. We give the class icons of Authorization and Account as an
example, see Figure 6-1.

Figure 6-1 Class icons with variables and operations needed for implementation

6.3. Some other implementation issues


One of the responsibilities of the Store object is to store all purchases. For the time being, we
will implement the storage in a text file. If we want to be able to inspect the purchases or to
search for a specific one, we may choose to store all Sale objects in a database. It also might
be useful to keep the inventory up to date. If we want to do that, the database may be of
service and the software needs more methods to keep the inventory up to date. To keep the
system simple enough we have skipped that part.

We have to select a proper programming language for the implementation. Several good
object-oriented programming languages are available, for example C++ and Java. For this
course we have selected Java because Java is safer and cleaner than C++. We need also a
programming environment, which makes it possible to edit the program code, debug the code
in case the developed code does not work properly, and to develop the graphical user
interface. Several environments are available on the market.

So-called CASE tools support preparing UML diagrams and monitor the consistency of the
different diagrams. Most CASE tools are able to prepare headings of classes and methods
based on the UML diagrams. It takes a long period to learn to work with CASE tools.
Therefore, we have decided not to use a CASE tool during this subject. For professional
projects, however, using a CASE tool may save time.

Most probably several programmers are involved in the implementation of the system. These
programmers will work concurrently and to be able to compile and debug the code, every
programmer starts to define the headings of all classes the programmer is responsible for.
Then the headings developed by one programmer will be sent to all other programmers
involved in the project. Every time a programmer has prepared a new version of a class, the
programmer will test whether the class functions properly, and send the new version to the
other programmers involved in the project. In reality they would use a common repository in
stead of sending files around. This process continues until the project manager is satisfied (or
time is over).

The next step is to implement the software in the supermarket that ordered the software. This
involves installing the software on the computers available in the supermarket and training the
people to use the software. This important part of the work includes, for example, training of

55
the cashiers and the manager of the supermarket. We do not describe that phase in this
document.

A good way to start the coding of a project is to translate the class icons of all classes into so-
called class skeletons in the implementation language (here Java). These are classes that
include only the information from the class icons and just enough extra code to prevent
compiler errors. In Java, this means that we have to supply empty bodies for constructors and
void methods, and for non-void methods the body should contain a return statement with a
return value of the appropriate type. Figure 6-2 gives an example class skeleton for the class
SalesLineItem developed before.

public class SalesLineItem {


private int quantity;
private double price;
private String description;
private String barcode;
private Item theItem;

public SalesLineItem (Item it, int quantity) {


}

public void setItem (Item it, int quantity) {


}

public double getPrice () {


return 0.0; // variant 1 to keep compiler happy
}

public String getDescription () {


return description; // variant 2 to keep compiler happy
}

public int getQuantity () {


int result = 1;
return result; // variant 3 to keep compiler happy
}
}

Figure 6-2 Class skeleton for SalesLineItem according to Figure 5-5

56

You might also like