7.12. (Optional) Software Engineering Case
Study: Collaboration Among Objects in the ATM System
In this section, we concentrate on the collaborations
(interactions) among objects in our ATM system. When two objects communicate
with each other to accomplish a task, they are said to collaborate—they do
this by invoking one another's operations. A collaboration consists of
an object of one class sending a message to an object of another class. Messages are sent in C++
via member-function calls.
In Section
6.22, we determined many of the operations of the
classes in our system. In this section, we concentrate on the messages that
invoke these operations. To identify the collaborations in the system, we return
to the requirements specification in Section
2.7. Recall that this document specifies the
range of activities that occur during an ATM session (e.g., authenticating a
user, performing transactions). The steps used to describe how the system must
perform each of these tasks are our first indication of the collaborations in
our system. As we proceed through this and the remaining Software Engineering
Case Study sections, we may discover additional collaborations.
Identifying the Collaborations in a
System
We identify the collaborations in
the system by carefully reading the requirements specification sections that
specify what the ATM should do to authenticate a user and to perform each
transaction type. For each action or step described, we decide which objects in
our system must interact to achieve the desired result. We identify one object
as the sending object (i.e., the object that sends the message) and another as
the receiving object (i.e., the object that offers that operation to clients of
the class). We then select one of the receiving object's operations (identified
in Section
6.22) that must be invoked by the sending object to
produce the proper behavior. For example, the ATM displays a welcome message
when idle. We know that an object of class Screen displays a message to
the user via its displayMessage operation.
Thus, we decide that the system can display a welcome message by employing a
collaboration between the ATM and the
Screen in which the ATM sends a displayMessage
message to the Screen by invoking the displayMessage operation
of class Screen. [Note: To avoid repeating the phrase "an object of class. . .,"
we refer to each object simply by using its class name preceded by an article
("a," "an" or "the")—for example, "the ATM"
refers to an object of class ATM.]
Figure
7.27 lists the collaborations that can be
derived from the requirements specification. For each sending object, we list
the collaborations in the order in which they are discussed in the requirements
specification. We list each collaboration involving a unique sender, message and
recipient only once, even though the collaboration may occur several times
during an ATM session. For example, the first row in Fig. 7.27 indicates that the
ATM collaborates with the Screen whenever the ATM needs to display a message to the user.
Fig. 7.27. Collaborations in the ATM
system.
| An object of class. . . |
sends the message. . . |
to an object of class. . . |
| ATM |
displayMessage |
Screen |
| |
getInput |
Keypad |
| |
authenticateUser |
BankDatabase |
| |
execute |
BalanceInquiry |
| |
execute |
Withdrawal |
| |
execute |
Deposit |
| BalanceInquiry |
getAvailableBalance |
BankDatabase |
| |
getTotalBalance |
BankDatabase |
| |
displayMessage |
Screen |
| Withdrawal |
displayMessage |
Screen |
| |
getInput |
Keypad |
| |
getAvailableBalance |
BankDatabase |
| |
isSufficientCashAvailable |
CashDispenser |
| |
debit |
BankDatabase |
| |
dispenseCash |
CashDispenser |
| Deposit |
displayMessage |
Screen |
| |
getInput |
Keypad |
| |
isEnvelopeReceived |
DepositSlot |
| |
credit |
BankDatabase |
| BankDatabase |
validatePIN |
Account |
| |
getAvailableBalance |
Account |
| |
getTotalBalance |
Account |
| |
debit |
Account |
| |
credit |
Account |
Let's consider the collaborations in Fig. 7.27.
Before allowing a user to perform any transactions, the ATM must prompt the user
to enter an account number, then to enter a PIN. It accomplishes each of these
tasks by sending a displayMessage message to the Screen. Both of these actions refer to the same
collaboration between the ATM and the Screen,
which is already listed in Fig. 7.27. The ATM obtains
input in response to a prompt by sending a getInput message to the
Keypad. Next, the ATM must determine whether
the user-specified account number and PIN match those of an account in the
database. It does so by sending an authenticateUser message to the BankDatabase. Recall that the BankDatabase cannot
authenticate a user directly—only the user's Account (i.e., the
Account that contains the account number
specified by the user) can access the user's PIN to authenticate the user. Figure 7.27 therefore lists a collaboration in which the
BankDatabase sends a validatePIN message to an
Account.
After the user is authenticated,
the ATM displays the main menu by sending a series of
displayMessage messages to the Screen and obtains input
containing a menu selection by sending a getInput message to the
Keypad. We have already accounted for these
collaborations. After the user chooses a type of transaction to perform, the
ATM executes the transaction by sending an execute message to an object of the appropriate
transaction class (i.e., a BalanceInquiry, a Withdrawal or a
Deposit). For example, if the user chooses to
perform a balance inquiry, the ATM sends an execute message to
a BalanceInquiry.
Further examination of the
requirements specification reveals the collaborations involved in executing each
transaction type. A BalanceInquiry
retrieves the amount of money available in the user's account by sending a
getAvailableBalance message to the BankDatabase, which responds by sending a getAvailableBalance
message to the user's Account. Similarly, the BalanceInquiry retrieves the amount of money on deposit by sending a
getTotalBalance message to the BankDatabase, which sends the same message to the user's
Account. To display both measures of the user's balance
at the same time, the BalanceInquiry sends a displayMessage
message to the Screen.
A Withdrawal sends the Screen several
displayMessage messages to display a
menu of standard withdrawal amounts (i.e., $20, $40, $60, $100, $200). The
Withdrawal sends the Keypad a getInput message to obtain the user's menu selection, then
determines whether the requested withdrawal amount is less than or
equal to the user's account balance. The Withdrawal can obtain the amount of money available in the account
by sending the BankDatabase a
getAvailableBalance message. The Withdrawal then
tests whether the cash dispenser
contains enough cash by sending the CashDispenser an
isSufficientCashAvailable message. A Withdrawal sends the
BankDatabase a debit message to
decrease the user's account balance. The BankDatabase sends the same message to the appropriate
Account. Recall that debiting funds from an
Account decreases both the totalBalance and the
availableBalance. To dispense the requested amount of cash, the
Withdrawal sends the CashDispenser a dispenseCash
message. Finally, the Withdrawal sends a displayMessage
message to the Screen, instructing the user to take the cash.
A Deposit responds to an execute message
first by sending a displayMessage message to the Screen to
prompt the user for a deposit amount. The Deposit sends a
getInput message to the Keypad to obtain the user's input. The
Deposit then sends a displayMessage message to the
Screen to tell the user to insert a deposit
envelope. To determine whether the deposit slot received an incoming deposit
envelope, the Deposit sends an isEnvelopeReceived message to
the DepositSlot. The Deposit updates the user's account by
sending a credit message to the BankDatabase, which
subsequently sends a credit message to the user's Account.
Recall that crediting funds to an Account increases the
totalBalance but not the availableBalance.
Interaction Diagrams
Now that we have identified a set of
possible collaborations between the objects in our ATM system, let us
graphically model these interactions using the UML. The UML provides several
types of interaction diagrams that model the behavior of a system by modeling how objects
interact with one another. The communication
diagram emphasizes which objects participate in collaborations. [Note: Communication diagrams were called collaboration diagrams in earlier versions of the
UML.] Like the communication diagram, the sequence
diagram shows collaborations among objects, but it emphasizes when messages are sent between objects over time.
Communication Diagrams
Figure
7.28 shows a communication diagram that models the ATM executing a
BalanceInquiry. Objects are modeled in the UML as
rectangles containing names in the form objectName
: ClassName. In this example, which involves
only one object of each type, we disregard the object name and list only a colon
followed by the class name. [Note: Specifying the name of each object in a communication
diagram is recommended when modeling
multiple objects of the same type.] Communicating objects are connected with
solid lines, and messages are passed between objects along these lines in the
direction shown by arrows. The name of the message, which appears next to the
arrow, is the name of an operation (i.e., a member function) belonging to the
receiving object—think of the name as a service that the receiving object
provides to sending objects (its "clients").

The solid filled arrow in Fig. 7.28 represents a message—or
synchronous call—in
the UML and a function call in C++. This arrow indicates that the flow of
control is from the sending object (the ATM) to the receiving object (a
BalanceInquiry). Since this is a synchronous
call, the sending object may not send another message, or do anything at all,
until the receiving object processes the message and returns control to the
sending object—the sender just waits. For example, in Fig. 7.28, the ATM calls
member function execute of a BalanceInquiry and may not send another message until
execute has finished and returns control to the ATM. [Note: If this were an asynchronous call,
represented by a stick arrowhead, the sending object would not have to wait for
the receiving object to return control—it would continue sending additional
messages immediately following the asynchronous call. Asynchronous calls often
can be implemented in C++ using platform-specific libraries provided with your
compiler. Such techniques are beyond the scope of this book.]
Sequence of Messages in a
Communication Diagram
Figure
7.29 shows a communication diagram that models the
interactions among objects in the system when an object of class
BalanceInquiry executes. We assume that the
object's accountNumber attribute contains
the account number of the current user. The collaborations in Fig. 7.29 begin after
the ATM sends an execute message to a
BalanceInquiry (i.e., the interaction modeled in Fig. 7.28). The number to the left of a message name indicates the
order in which the message is passed. The sequence
of messages in a communication diagram
progresses in numerical order from least to greatest. In this diagram, the
numbering starts with message 1 and ends with message 3. The
BalanceInquiry first sends a getAvailableBalance message to the
BankDatabase (message 1), then sends a
getTotalBalance message to the BankDatabase (message
2). Within the parentheses following a message
name, we can specify a comma-separated list of the names of the parameters sent
with the message (i.e., arguments in a C++ function call)—the
BalanceInquiry passes attribute accountNumber with its
messages to the BankDatabase to indicate which Account's
balance information to retrieve. Recall from Fig.
6.35 that operations getAvailableBalance and
getTotalBalance of class BankDatabase each require a parameter
to identify an account. The BalanceInquiry next displays the
availableBalance and the totalBalance to the user by passing a
displayMessage message to the Screen (message 3) that
includes a parameter indicating the message to be displayed.

Figure
7.29 models two additional messages passing from the BankDatabase
to an Account (message 1.1 and message 2.1). To
provide the ATM with the two balances of the user's Account
(as requested by messages 1 and 2), the BankDatabase
must pass a getAvailableBalance and a getTotalBalance message
to the user's Account. Messages passed within the handling of another
message are called nested messages. The UML recommends using a decimal numbering scheme
to indicate nested messages. For example, message 1.1 is the first message nested in message 1—the
BankDatabase passes a getAvailableBalance message while
processing BankDatabase's message of the same
name. [Note: If the BankDatabase needed to pass a second nested message while processing
message 1, the second message would be
numbered 1.2.] A message may be passed only
when all the nested messages from the previous message have been passed—e.g.,
the BalanceInquiry passes message 3 only after messages
2 and 2.1 have been passed, in that order.
The nested numbering scheme used
in communication diagrams helps clarify precisely when and in what context each
message is passed. For example, if we numbered the messages in Fig. 7.29 using a flat numbering
scheme (i.e., 1, 2, 3, 4, 5), someone looking at the diagram might not be able to
determine that BankDatabase passes the getAvailableBalance
message (message 1.1) to an Account during the BankDatabase's processing of
message 1, as opposed to after completing the processing of message 1. The nested
decimal numbers make it clear that the second getAvailableBalance
message (message 1.1) is passed to an Account within the
handling of the first getAvailableBalance message (message 1)
by the BankDatabase.
Sequence Diagrams
Communication diagrams emphasize the
participants in collaborations but model their timing a bit awkwardly. A
sequence diagram helps model the timing of collaborations more clearly. Figure 7.30 shows a sequence diagram modeling the sequence of
interactions that occur when a Withdrawal
executes. The dotted line extending down from an object's rectangle is that
object's lifeline, which represents the progression of time. Actions
typically occur along an object's lifeline in chronological order from top to
bottom—an action near the top typically happens before one near the
bottom.
Message passing in sequence
diagrams is similar to message passing in communication diagrams. A solid arrow
with a filled arrowhead extending from the sending object to the receiving
object represents a message between two objects. The arrowhead points to an
activation on the receiving object's lifeline. An activation, shown as a thin
vertical rectangle, indicates that an object is executing. When an object
returns control, a return message, represented as a dashed line with a stick
arrowhead, extends from the activation of the object returning control to the
activation of the object that initially sent the message. To eliminate clutter, we omit the return-message
arrows—the UML allows this practice to make diagrams more readable. Like
communication diagrams, sequence diagrams can indicate message parameters
between the parentheses following a message name.
The sequence of messages in Fig. 7.30 begins when a
Withdrawal prompts the user to choose a withdrawal amount
by sending a displayMessage message to the
Screen. The Withdrawal then sends a getInput message
to the Keypad, which obtains input from the
user. We have already modeled the control logic involved in a
Withdrawal in the activity diagram of Fig.
5.22, so we do not show this logic in the sequence
diagram of Fig.
7.30. Instead, we model the best-case scenario in
which the balance of the user's account is greater than or equal to the chosen
withdrawal amount, and the cash dispenser contains a sufficient amount of cash to satisfy the
request. For information on how to model control logic in a sequence diagram,
please refer to the web resources and recommended readings listed at the end of
Section
2.7.
After obtaining a withdrawal amount, the Withdrawal
sends a getAvailableBalance message to the BankDatabase, which
in turn sends a getAvailableBalance message to the user's
Account. Assuming that the user's account
has enough money available to permit the transaction, the Withdrawal
next sends an isSufficientCashAvailable message to the
CashDispenser. Assuming that there is enough
cash available, the Withdrawal decreases the balance of the user's
account (i.e., both the totalBalance and the availableBalance)
by sending a debit message to the BankDatabase. The
BankDatabase responds by sending a debit message to the user's
Account. Finally, the Withdrawal sends a dispenseCash
message to the CashDispenser and a displayMessage message to
the Screen, telling the user to remove the cash from the machine.
We have identified the collaborations
among objects in the ATM system and modeled some of these collaborations using
UML interaction diagrams—both communication diagrams and sequence diagrams. In
the next Software Engineering Case Study section (Section
9.11), we enhance the structure of our model to
complete a preliminary object-oriented design, then we begin implementing the
ATM system.
Software Engineering Case Study
Self-Review Exercises
| 7.1 |
A(n)__________ consists of an object
of one class sending a message to an object of another class.
|
| 7.2 |
Which form of interaction
diagram emphasizes what collaborations occur? Which form emphasizes when collaborations occur? |
| 7.3 |
Create a sequence diagram that
models the interactions among objects in the ATM system that occur when a
Deposit executes successfully, and explain the sequence of messages
modeled by the diagram. |
Answers to Software Engineering
Case Study Self-Review Exercises
| 7.1 |
c. |
| 7.2 |
Communication diagrams emphasize what collaborations occur. Sequence diagrams emphasize
when collaborations occur. |
| 7.3 |
Figure
7.31 presents a sequence diagram that models the
interactions between objects in the ATM system that occur when a
Deposit executes successfully. Figure 7.31 indicates that a
Deposit first sends a displayMessage message to the
Screen to ask the user to enter a deposit
amount. Next the Deposit sends a getInput message to the
Keypad to receive input from the user. The
Deposit then instructs the user to enter a
deposit envelope by sending a displayMessage
message to the Screen. The Deposit next sends an
isEnvelopeReceived message to the DepositSlot to confirm that the deposit envelope has been received
by the ATM. Finally, the Deposit increases the totalBalance
attribute (but not the availableBalance attribute) of the user's
Account by sending a credit message to the
BankDatabase. The BankDatabase responds
by sending the same message to the user's Account.
|