Anda di halaman 1dari 25

Introduction to the UML Page 1

Introduction to the UML


Civil Engineering with Computing
by Andrew Bond (Geocentrix Ltd)
www.geocentrix.co.uk/oop

What is the UML?


The Unified Modeling Language (UML) is a graphical language for visualizing, specifying,
constructing, and documenting the artifacts of a software-intensive system
Grady Booch, James Rumbaugh, and Ivar Jacobson (1999)
The Unified Modeling Language User Guide, pXV

The UML:
# Provides a standard means of expressing design that reflects the best practices of industry
# Aims to de-mystify the process of software system modelling
# Adopts the best of the Booch, Rumbaugh, & Jacobson (the three amigos) notations
# Has been accepted as a standard by the Object Management Group (OMG) - an industry-wide
body

The 4+1 view model


The architecture of software-intensive systems
can best be described by five interlocking Design view Implementation view
views, each of which is a projection into the
organization and structure of the system.
Use case view
The use case view encompasses the use cases
that describe the behaviour of the system to its
end-users. Process view Deployment view

The design view encompasses the classes,


interfaces, and collaborations that describe the <---logical physical--->
problem and its solution. This view primarily Figure 1. 4+1 view model (Booch et al, p31)
supports the functional requirements of the
system.

The process view encompasses the threads and processes that form the systems concurrency and
synchronization mechanisms. This view primarily addresses the performance, scalability, and
throughput of the system.

The implementation view encompasses the components and files that are used to assemble and
release the system. The static aspects of this view are captured in component diagrams; the
dynamic aspects in interaction, statechart, and activity diagrams.

The deployment view encompasses the nodes that form the systems hardware topology. This view
addresses the distribution, delivery, and installation of the system.

UML diagrams
The UML defines various diagrams that can be used to visualize the static and dynamic parts of a
computer system:
Introduction to the UML Page 2

Diagram

Static diagram Dynamic diagram

Class Object Use case

Component Deployment Collaboration Sequence

Statechart Activity

Figure 2. UML diagrams

Use case diagrams


Use case diagrams help you to visualize the relationships between use cases and actors. Use case
diagrams show the dynamic behaviour of a system.

Set Limits Update Accounts

Accounting System

Trading Manager
Analyze Risks
uses

uses
Valuation
Price Deal

Trader Capture Deal

extends

Salesperson

Limits Exceeded

Figure 3. Example of a use case diagram (Fowler and Scott, p45)

Use cases
A use case describes a sequence of actions that a system performs on behalf of
an actor (see below). In the UML, a use case is represented by an ellipse Deposit money
containing the name of the use case. In the example here (taken from a banking
application), a use case named Deposit money is defined.
Introduction to the UML Page 3

A use case describes what a system does, but does not specify how it does it.

Actors
An actor is a role that a user plays when interacting with the computer system. In this
context, a user may be a human, a hardware device, or even another computer system. In
the UML, an actor is represented by a stick figure with the name of the actor beneath it. In
the example here, an actor named Customer is defined.

An actor describes who uses the system. Customer

System boundaries
A system boundary is exactly what its name implies: the boundary of some Bank
system. In the UML, a system boundary is represented by a rectangular
box with the name of the system inside it. In the example here, the system
boundary of a bank is shown.

Associations
In a use case diagram, an association typically represents a Bank
relationship between an actor and one or more use cases.
Associations are represented in the UML by straight lines Deposit money
connecting the actor to the use cases he or she carries out. In
the example here, the customer deposits money, withdraws
money, and orders a statement all of which are within the
boundaries of the banks system.
Withdraw money

Actors may be connected to use cases only by association.


An association between an actor and a use case indicates Customer

that they communicate with each other, possibly by sending


Order statement
and receiving messages.

Generalization of actors
In a use case diagram, you can define general types of actors and
specialize them using generalization relationships.

Generalization is represented in the UML by a white arrowhead


pointing from the specialized thing to the generalized thing. In the Customer
example here, Commercial Customer is a special type of Customer
(and Customer a general type of Commercial Customer).
Commercial Customer
Generalization of use cases
In a use case diagram, you can also define
Deposit money Withdraw money
general types of use cases and specialize
them using generalization relationships.
extends extends
As for actors, generalization of use cases is Order statement

represented in the UML by a white


arrowhead pointing from the specialized to uses
Money transaction
the generalized use case. However, these
uses
relationships are typically stereotyped by one
Validate account
of two keywords, extends or uses, depending number

on their intent:
# Extends indicates that the specialized use
case is similar to the general use case but does something more (typically, the extended use
case deals with a variation of the general use case)
Introduction to the UML Page 4

# Uses indicates that the specialized use case is a common part of several use cases and has been
factored out to avoid repetition

In the example here, Deposit money and Withdraw money both extend Money transaction. Order
statement and Money transaction both use Validate account number. Since generalization
relationships are transitive, this implies that Deposit money and Withdraw money also use Validate
account number.

Example from the literature


The use case diagram at the start of this section shows a financial trading system. There are four
actors involved (Trading Manager, Trader, Salesperson, and Accounting System) and seven use
cases.

The relationships between the actors and use cases are as follows:
# The Trading Manager sets limits
# The Trader analyses risks, prices deals, and captures deals
# The Salesperson also captures deals
# The Accounting System updates accounts
# Two uses cases (Analyze Risks and Price Deals) use the Valuation use case
# The use case Limits Exceeded extends Capture Deal

Class diagrams
Class diagrams help you to visualize the relationships between classes, interfaces, and
collaborations. Class diagrams show the static (structural) design of a system.

0..1 -chairperson 0..1

University Department Instructor

-name : std::string -name : std::string -name : std::string


-address : std::string 1
+Add(in who : Instructor)
-phone_number : std::string 1..*
+Remove(in who : Instructor)
+Add(in who : Student) +GetAllInstructors()
+Remove(in who : Student) 1..* 1..*
+GetAllStudents()
1..* 1..*
+Add(in which : Department)
+Remover(in which : Department) <assigned to
+GetAllDepartments()

1..*

<member

* 1..*
<teaches

Student * Course *
attends>
-name : std::string -name : std::string
-id : int -id : int
*

Figure 10. Example class diagram (based on Figure 8-3 of Booch et al., 1999)
Classes
In the UML, a class is represented by a rectangle containing the
name of the class. In the example here, a class named Person is Person
defined.

// C++ example
class Person {};
Introduction to the UML Page 5

Associations
An association is a relationship in which an object of one type is connected to an object of another
type.

Associations are owns>


represented in the UML Person Dog
by lines connecting the
respective classes. To
improve understanding,
associations may be named by placing a word or words above or below the connecting line. The
direction in which the name is read is indicated by an (optional) arrow. In the example here, the
person owns the dog.

The roles played by each pet


class in an association
may be named by placing Person Dog
a word or words at the owner
ends of the association. In
the example here, the
person is the owner of the dog and the dog is the persons pet.

In many situations, one or more objects of a particular class may be associated with one or more
objects of another class. This is called the multiplicity of the association and is represented by
numbers placed at the ends of the association:
# 1 means exactly one object of this class is involved in the association
# 0..1 means either zero or one objects are involved
# 0..* means zero or more objects are involved
# 1..* means one or more objects are involved
# n (where n is an integer) means exactly that number of objects are involved

In the example here, the 1


person owns zero or
more dogs, but each dog Person Dog
is owned by exactly one 0..*
person.

Associations that
represent whole/part or
has-a relationships Family Person
between classes are
known as aggregation.
Aggregation is
represented in the UML by adding a diamond next to the aggregate class. In the example here,
Family represents the whole and Person the part.

// C++ example
// decision to use a set is an implementation detail
#include <set>

class Person {};


class Family
{
std::set<Person*> members; // not owned by Family
};
Introduction to the UML Page 6

Specifying multiplicities in 0..*


this example adds
information that will be Family Person
useful during the 2..*
implementation of class
Family. Assuming that a
family must consist of at least two people and that any one person can be a member of zero, one,
or more families (e.g. through marriage), the UML class diagram representing this association is
shown above.

There is a special form of 1


aggregation in which the <is attached to
lifetime of the part Person Arm
corresponds to that of the 2
whole. This owns-a
relationship is known as
composition and is represented in the UML by a black diamond next to the aggregate class. In the
example here, the person has exactly two arms (assuming that he/she has not lost one due to an
accident!) and each arm is an integral part of exactly one person (assuming we are not modelling
transplants!). When the person dies (i.e. an object of class Person is destructed), the arms die too
(i.e. both objects of class Arm are destructed too).

// C++ example
class Arm {};
class Person
{
// created/destroyed at the same time as Person...
Arm left_arm;
Arm right_arm;
};

Generalization
Generalization is a relationship between classes in which one class (the derived or child class) is
a more specialized version of the other (the base or parent class). Generalization represents is-
a relationships between classes.

Generalization is represented in the UML by a white arrowhead pointing


to the more general class. In the example here, the class Alsatian is derived Dog
from the class Dog, indicating that an Alsatian is a more specialized
version of dog (and a dog is a more generalized version of an Alsatian). In
this class hierarchy, Dog is Alsatians parent and Alsatian is Dogs child.

// C++ example Alsatian


class Dog {};
class Alsatian : public Dog {};
/* When a class is derived publically from another class, the child
class has access to all its parents public and protected member
variables/functions. If you omit the keyword public, then the class
is derived privately from its parent - and only the parents public
member variables/functions are accessible. In most cases you want
public derivation. */

A class that has no parents is called a root class and one that has no children is called a leaf.
Introduction to the UML Page 7

Polymorphic classes allow their operations to be


chosen at run-time according to the type of object Animal
for which the operation is called. Abstract classes
are incomplete (they have at least one operation
which is undefined, although its signature is given)
and cannot be created the compiler will ensure
this. By contrast, concrete classes are complete (all Dog
their operations are defined) and therefore can be
created. Abstract classes are indicated in the UML
by writing their names in italics: concrete classes
are indicated by normal text.

In the example here, Animal is an abstract root


class, whereas Alsatian and Labrador are concrete
leaf classes. Alsatian Labrador

// C++ example
class Animal
{
protected:
Animal(); // default ctor accessible to derived classes only
};
class Dog : public Animal {};
class Alsatian : public Dog {};
class Labrador : public Dog {};

Specialization is a transitive relationship: an Alsatian is-a Dog and a Dog is-a(n) Animal implies
that an Alsatian is-a(n) Animal.

Classes that derive from more than one


parent are said to be multiply-inherited. In Cricketer
the example here, class AllRounder is
derived from both Bowler and Batsman,
who in turn are derived from Cricketer. An
AllRounder is therefore also a Cricketer
(twice over, in fact a problem that makes
multiple inheritance tricky to implement
correctly and a reason why Java does not
allow it). Bowler Batsman

// C++ example
class Cricketer {};
class Bowler :
public Cricketer {};
class Batsman :
public Cricketer {};
class AllRounder : AllRounder
public Bowler, public
Batsman {};

Attributes, operations, and responsibilities


Class icons can be divided into compartments to show the classs
attributes, operations, and responsibilities: Class
# Attributes (C++ member variables) are shown in a compartment just
below the class name attribute
# Operations (C++ member functions) are shown in a compartment just operation()
below the class attributes
Introduction to the UML Page 8

# Responsibilities are (optionally) shown in a separate compartment at the bottom of the class
icon

When drawing a class diagram, you may choose to show or hide any of the compartments (other
than the one that names the class, which must always be present).

The visibility of each attribute/operation is indicated by a symbol


placed in front of its name:
ClassShowingVisibilities
# + for public visibility: this attribute/operation can be accessed
by functions in any part of the program +public_attribute
# # for protected visibility: this attribute/operation can be #protected_attribute
-private_attribute
accessed by functions in the class itself or any class derived from
+PublicOperation()
it #ProtectedOperation()
# - for private visibility: this attribute/operation can be accessed -PrivateOperation()
by functions in this class alone

// C++ example
class ClassShowingVisibilities
{
private:
int private_attribute;
void PrivateOperation();
protected:
int protected_attribute;
void ProtectedOperation();
public:
int public_attribute;
void PublicOperation();
};

Class attributes/operations (e.g. C++ static member


variables/functions) are underlined. ClassShowingClassScope

// C++ example per_instance_attribute


class ClassShowingClassScope per_class_attribute
{ PerInstanceOperation()
int per_instance_attribute; PerClassOperation()
static int per_class_attribute;
void PerInstanceOperation();
static void PerClassOperation();
};

The syntax for describing attributes is as follows:

name : type = initial_value

and that for describing operations:

name(argument_name : type = default_value, ...) : return_type

In the example here, Person has one private attribute: his


or her age (of type int) and five operations, all of which Person
are public. Persons constructor takes no arguments and
-age : int
returns nothing; CelebrateBirthday and
+Person()
DiscoverSecretOfYouth take no arguments and return +CelebrateBirthday() : void
void; GrowOldFast takes one argument (an int, which +DiscoverSecretOfYouth() : void
takes a default value of 10 if not specified) and returns +GrowOldFast(in years : int = 10) : void
+HowOld() : int
Introduction to the UML Page 9

void; and HowOld takes no arguments and returns an int.

// C++ example
class Person
{
private:
int age; // in years
public:
Person(); // set age to 0 years
void CelebrateBirthday(); // increase age by 1 year
void DiscoverSecretOfYouth(); // decrease age by 10 years
void GrowOldFast(int years = 10); // increase age by value of
years
int HowOld() const; // return age
};

Polymorphic operations are chosen at run-time according to the type of object for which the
operation is called. Abstract operations are incomplete, i.e. the operations signature is declared but
no body is defined; whereas concrete operations have both a signature and a body. Abstract
operations are indicated in the UML by writing their names in italics: concrete operations are
indicated by normal text.

Animal

+Speak(in os : std::ostream&) : void

Dog Cat Mouse

+Speak(in os : std::ostream&) : void +Speak(in os : std::ostream&) : void +Speak(in os : std::ostream&) : void

In the example here, Speak is an abstract operation in class Animal but a concrete operation in
classes Dog, Cat, and Mouse. Thus if the operation Speak is called for an object of type Cat, it is
Cats version of Speak that gets called.

Dependencies
Animal
A dependency is a
relationship in which
an object of one
type uses an object
of another type, and
therefore depends
on it. Dependencies
Dog Cat Mouse
are represented in
the UML by a
dashed line with an
open arrow pointing
from the dependent std::ostream
class to the class it
Introduction to the UML Page 10

depends upon. In the example here, Animal, Dog, Cat, and Mouse all depend on std::ostream,
because the latter class is an argument in their operation Speak (which is not shown on this
diagram). If the specification of std::ostream should change, then all of these classes would need to
be re-compiled.

Example from the literature


The class diagram at the start of this section shows the associations between a number of classes
that might be used to model a University teaching programme. The diagram describes five classes,
University, Department, Course, Student, and Instructor, each of which has a name (modelled by a
string from the standard library), some of which have an ID number, and one of which has an
address and phone number.

The relationships between these classes are as follows:


1. The University has one or more Departments
2. Each Department belongs to only one University
3. The University has a any number of Students
4. Each Student is a member of one or more Universities
5. Each Student attends any number of Courses and each Course has any number of Students on
it
6. Each Instructor teaches on any number of Courses and each Course has one or more
Instructors
7. Each Course is associated with one or more Departments and each Department is associated
with one or more Courses
8. Each Instructor is assigned to one or more Departments; and is the chairperson of zero or one
Departments
9. Each Department has one or more Instructors and either zero or one Instructors as a
chairperson

The classes University and Department has operations for adding, removing, and getting the objects
they aggregate. Departments Add() and Remove() operations take a single parameter named who
of type Instructor; the UML diagram does not indicate the return type of Departments operation
GetAllInstructors(), indicating that this is an implementation detail.

Object diagrams
Object diagrams show a set of
objects at a specific moment in
time. : Car : Engine

Objects
Objects are shown by simple
rectangles, with the name and
type of object underlined:

Vauxhall : Car
: Wheel : Wheel : Wheel : Wheel
Where the name of the object
is irrelevant, it can be omitted:

: Car

When the name of the object is relevant, but not its type, the type may be omitted:

Vauxhall :
Introduction to the UML Page 11

Links
Links are shown by solid lines joining the objects which are linked.

Similarity to class diagrams


Object diagrams are closely related to class 1
diagrams, as the diagram here illustrates. In object Car Engine
diagrams, names are underlined and multiple
1
objects are represented by separate boxes rather
1
than numbers at one end of a link.
4
Sequence diagrams
Sequence diagrams are interaction diagrams that
Wheel
emphasize the time ordering of messages.
Sequence diagrams show objects arranged along
the top X-axis and messages, ordered in increasing
time, along the Y-axis.

Objects
Objects are shown by simple
rectangles, with the name and type of : VideoStore

object underlined: : Customer : Clerk : Manager

Report loss of tape()


Blockbuster : VideoStore Get record of rental()

Look up rental()
Where the name of the object is Return rental()
irrelevant, it can be omitted: Refer to Manager()

Talk to Manager()
: VideoStore Look up tape history()

If an object represents an actor in the Find tape records()

system, then a stick figure can be Return record()

Negotiate fee()
: Diner : Waiter : Chef
used in place of the rectangle.
Pay()

Order()
Lifelines
Communicate order()
An objects lifeline represents the time
it remains in existence. During that <<create>>()
existence, there are times when the Figure 29. Example sequence diagram (Liberty, 1998, p50)
m : Meal
object will be active (denoted by a
Ready()
wide band) and times when it is
inactive (denoted by a dashed line).
Cook()

Ready()
If an object is created during the time Ready()
span covered by the sequence
diagram, then its symbol is placed at Collect()
the point it first comes into existence Serve()
(see the example showing m : Meal
coming into existence once it has Eat()

been created by the : Chef).


Request bill()

The end of an objects lifeline is Bill()

denoted by a cross. Pay()

Messages
Messages are shown by solid lines
Introduction to the UML Page 12

with solid arrows pointing to the recipient of the message. The duration of a message is represented
by the vertical distance between the beginning and end of the line. Thus, an instantaneous message
is denoted by a horizontal line (e.g. Order() in the example alongside) and a message taking some
time by a sloping line (e.g. Cook()).

The response to a message is denoted by a dashed line.

Each message has a name which represents the function call that implements the message.
Parameters can be shown within the brackets after the message name, if desired.

A message that involves creation of another object is labelled <<create>>.

Collaboration diagrams
Collaboration diagrams are interaction 1. Report loss of tape()
diagrams that emphasize the 5. Refer to Manager()

organization of the objects that


participate in an interaction.
Collaboration diagrams are similar to : Clerk
: Customer
object diagrams in the way they show

rd() l()
a
objects and the links between them.

rn r f rent
eco
o
In addition, collaboration diagrams
6. T Nego ay()

4. R record
10. 11. P
alk

show the direction of messages

etu
to m te fee

et
2. G
between the objects.
tia
ana ()
ger
()

Objects

8. Find tape records()


3. Look up rental()
Objects are shown by simple istor
y()
pe h )
rectangles, with the name and type of o k up ta record( : VideoStore
o
7. L Return
9.
object underlined. If an object
represents an actor in the system,
then a stick figure can be used in
place of the rectangle.
: Manager

Messages Figure 31. Example collaboration diagram (Liberty, 1998,


Messages are shown by solid lines p61)
with solid arrows pointing to the
recipient of the message. The ordering of messages is denoted by a sequence of numbers and/or
letters: e.g. 1, 2, 3a, 3b, 3c, 4, 5. The name of the message follows its order number.
Introduction to the UML Page 13

()
rder
1. O erve() l()
9. S uest bil 2. C
om
. Req Bill() mu
11
12. ay()
: Waiter 7. R nicate
P ead ord
13. y() er()

: Diner : Chef

8. Coll

R oo y( ()
ect()

6. . C ead are
ea k( )
5 R p
4. Pre

dy )
10

()
. Ea

3.
t( )

m : Meal

Activity diagrams
Activity diagrams show the flow from activity to activity. An activity is an on-going non-atomic
execution within a state machine. Activities ultimately result in some action, which results in a
change of state of the system or the return of a value.
Introduction to the UML Page 14

[no coffee]
Find beverage

[found coffee]

[found cola]

Put coffee in filter Add water to reservoir Get cups Get can of cola

[no cola]
Put filter in machine

Turn on machine

Brew coffee

Pour coffee Drink beverage

Action and activity states


An action state is represented in the UML by a rectangle
with rounded corners, containing the Develop plan count := count + 1
name of the action. An action can be
described by the use of simple text,
such as Develop plan, or by an expression, such as count := count + 1. The
example here shows both forms of action state.

An activity state is also represented by a rectangle with rounded corners,


Select site
containing the name of the activity.

Initial and final states are represented by black circles without or with
(respectively) a surrounding ring. In the example here, the initial state leads into
the action state Select site and Commission architect is the last action state
before the final state.
Commission architect
Transitions
A transition is represented by a solid line with an open arrow at one end.

Branches and guards


Branches are represented in one of two ways: either explicitly, by a small white
Introduction to the UML Page 15

diamond, or implicitly, by multiple transitions leaving an activity or action state.

In the example above, the activity Find beverage branches according to whether coffee is found or
not. If it is not, a further branch occurs, depending on whether cola is found or not.

Forking and joining


A fork is denoted by a thick line from which several transitions leave but only one enters. A join is
denoted by a thick line from which one transition leaves but several enter.

Swimlanes
Sometimes it is helpful to place activities in what a re termed swimlanes which represent different
parts of the system. Swimlanes are separated from each other by vertical lines.

Statechart, component, and deployments diagrams


...are outside the scope of this workshop. Please refer to the books below for further information.

References
UML
nd
1. Martin Fowler with Kendal Scott (1999), UML Distilled (2 edition), Addison-Wesley, 224pp,
(ISBN 0-201-65783X), 19
2. Grady Booch, James Rumbaugh, & Ivar Jacobson (1999), The Unified Modeling Language User
Guide, Addison-Wesley, 482pp (ISBN 0-201-57168-4), 38
3. Jesse Liberty (1998), Beginning Object-Oriented Analysis and Design with C++, Wrox Press,
(ISBN 1-861001-33-9), 33
4. Pierre-Alain Muller (1997), Instant UML, Wrox Press, 343pp (ISBN 1-861000-87-1), 21
5. Rob Pooley & Perdita Stevens (1999), Using UML, Addison-Wesley, 255pp (ISBN
0-201-36067-5), 25
Prices quoted by Amazon.co.uk (January 2001)
Introduction to the UML Page 16

Class exercises
Exercise 1
# Identify the actors and use cases for a computerised version of the classic card game Pontoon.

Exercise 2
# Identify a set of classes to implement Pontoon, including the relationships between them. Draw
a class diagram corresponding to these classes and relationships.
# Develop C++ code to implement the class diagram.

Exercise 3
# Draw an object diagram representing a particular moment during a game of Pontoon, when a
player has the following card: Ace of Spades, 3 of Diamonds, and 7 of Hearts

Exercise 4
# Draw either a sequence diagram or a collaboration diagram to represent playing of a single
hand of Pontoon
Introduction to the UML Page 17

Rules of Pontoon
From The Penguin Book of Card Games, by David Parlett (1978), Penguin Books, 474pp (ISBN 0 14
046 344 5)

A banking game for 3-10 players, 4-6 best. Use a standard 52-card pack. Suits are irrelevant: all that
counts is the numerical face-value of the cards:
# From Two to Ten count 2 to 10 respectively
# Court cards count 10 each
# An ace counts either 1 or 11 at its holder's discretion

Banker...
# Shuffles the cards before his first deal, but not thereafter
# Deals one card each, face down, dealer's last

All except the banker may look at their card. Everyone gets a second card and more may be bought
thereafter. The object is to finish with a better hand than the banker's

A hand whose cards total over 21 is bust and loses. A hand totalling 16-21 beats the banker only if
the latter has a lower count or is bust. There are three special hands:
# Pontoon is 21 on two cards
# Royal Pontoon is three Sevens (punter only)
# A five card trick is a hand of five cards that is not bust

Pontoon beats the banker unless he also has a pontoon and wins double. Royal Pontoon beats the
banker and wins treble. Three Sevens for the banker counts as 21 and is beaten by pontoon. A five
card trick beats anything the banker has, except another five card trick, and wins double.

Each punter looks at his first card and stakes upon it an amount that lies within previously agreed
limits, and then gets a second card (as does the banker). If the banker has pontoon he reveals it and
wins, collecting double everyone's stakes. If a punter has pontoon, he turns the ace over and
receives no more cards.

A punter with two cards of identical rank may split them and play two hands, staking the same
amount on the second hand as on the first. The banker may not split. The punter then either:
# Sticks, provided his score is 16 or over
# Buys a card (dealt face down)
# Twists a card (dealt face up)
The punter may not buy after twisting.

When buying a card, the punter pays not less than what he paid for his previous card nor more than
his total stake so far. The fifth card of a five card trick is always dealt face up, even if bought. The
banker plays after all the punter have played and pays only those punters who have beaten his
score.
Introduction to the UML Page 18

Program 1
//----------------------------------------------------------------------------
// Civil Engineering with Computing: OOP with C++, UML, and the STL
// Introduction to the UML
// Copyright: 2001 Geocentrix Ltd. All Rights Reserved.
// Component: Program1.exe
// File: Program1.cpp
// Overview: implementation of Program1
//---------------------------------------------------------------------------
#include <iostream>

using std::cout;
using std::endl;

//---------------------------------------------------------------------------
// class Person

class Person
{
public:
Person() {
cout << "Person born" << endl;
}
~Person() {
cout << "Person dies" << endl;
}
};

//---------------------------------------------------------------------------
// main test program

int main()
{
cout << "About to create a person" << endl;
Person me;
cout << "About to return from main()" << endl;
return 0;
}
//---------------------------------------------------------------------------
// Revision history
// 1.00 29/01/01 AJB modified for Feb 2001 class
// 1.10 28/09/01 AJB modified for Sept 2001 class
//----------------------------------------------------------------------------

Program 2
//----------------------------------------------------------------------------
// Civil Engineering with Computing: OOP with C++, UML, and the STL
// Introduction to the UML
// Copyright: 2001 Geocentrix Ltd. All Rights Reserved.
// Component: Program2.exe
// File: Program2.cpp
// Overview: implementation of Program2
//---------------------------------------------------------------------------
#include <iostream>
Introduction to the UML Page 19

#include <string>

using std::cout;
using std::endl;
using std::string;

//---------------------------------------------------------------------------
// class Person

class Person
{
public:
Person(const string& a_name);
~Person();
string Name() const {
return name;
}
private:
string name;
};

Person::Person(const string& a_name)


: name(a_name)
{
cout << Name() << " born" << endl;
}

Person::~Person()
{
cout << Name() << " dies" << endl;
}

//---------------------------------------------------------------------------
// main test program

int main()
{
cout << "About to create a person" << endl;
Person me("Andrew");
cout << "My name is " << me.Name() << endl;
cout << "About to return from main()" << endl;
return 0;
}
//---------------------------------------------------------------------------
// Revision history
// 1.00 29/01/01 AJB modified for Feb 2001 class
// 1.10 28/09/01 AJB modified for Sept 2001 class
//----------------------------------------------------------------------------

Program 3
//----------------------------------------------------------------------------
// Civil Engineering with Computing: OOP with C++, UML, and the STL
// Introduction to the UML
// Copyright: 2001 Geocentrix Ltd. All Rights Reserved.
Introduction to the UML Page 20

// Component: Program3.exe
// File: Program3.cpp
// Overview: implementation of Program3
//---------------------------------------------------------------------------
#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;
using std::ostream;

//---------------------------------------------------------------------------
// class Person

class Person
{
public:
Person(const string& firstname, const string& surname, bool male);
~Person();
string Name() const {
return firstname + " " + surname;
}
unsigned int Age() const {
return age;
}
void CelebrateBirthday() {
++age;
}
bool IsMale() const {
return male;
}
bool IsFemale() const {
return !IsMale();
}
void Speak(ostream& os) const;
private:
string firstname;
string surname;
bool male;
unsigned int age;
};

Person::Person(const string& firstname, const string& surname, bool male)


: firstname(firstname)
, surname(surname)
, male(male)
, age(0)
{
cout << Name() << " born" << endl;
}

Person::~Person()
{
Introduction to the UML Page 21

cout << Name() << " dies" << endl;


}

void Person::Speak(ostream& os) const


{
os << "My name is " << Name() << endl;
os << "I am a ";
if(IsMale())
os << "male";
else
os << "female";
os << " aged " << Age() << endl;
}

//---------------------------------------------------------------------------
// main test program

int main()
{
cout << "Create a person" << endl;
Person me("Andrew", "Bond", true);
me.Speak(cout);

cout << "Live 40 uneventful years" << endl;


for(unsigned int i = 0; i < 40; ++i)
me.CelebrateBirthday();
me.Speak(cout);

cout << "About to return from main()" << endl;


return 0;
}
//---------------------------------------------------------------------------
// Revision history
// 1.00 29/01/01 AJB modified for Feb 2001 class
// 1.10 28/09/01 AJB modified for Sept 2001 class
//----------------------------------------------------------------------------

Program 4
//----------------------------------------------------------------------------
// Civil Engineering with Computing: OOP with C++, UML, and the STL
// Introduction to the UML
// Copyright: 2001 Geocentrix Ltd. All Rights Reserved.
// Component: Program4.exe
// File: Program4.cpp
// Overview: implementation of Program4
//---------------------------------------------------------------------------
#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;
using std::ostream;
Introduction to the UML Page 22

//---------------------------------------------------------------------------
// class Person

class Person
{
public:
Person(const string& firstname, const string& surname, bool male);
~Person();
string Name() const {
return firstname + " " + surname;
}
unsigned int Age() const {
return age;
}
void CelebrateBirthday() {
++age;
}
bool IsMale() const {
return male;
}
bool IsFemale() const {
return !IsMale();
}
void Speak(ostream& os) const;
bool CanMarry() const;
void Marry(Person& fiancee);
bool IsMarried() const {
return spouse;
}
private:
string firstname;
string surname;
bool male;
unsigned int age;
const Person* spouse;
};

Person::Person(const string& firstname, const string& surname, bool male)


: firstname(firstname)
, surname(surname)
, male(male)
, age(0)
, spouse(0)
{
cout << Name() << " born" << endl;
}

Person::~Person()
{
cout << Name() << " dies" << endl;
}

bool Person::CanMarry() const


{
Introduction to the UML Page 23

if(IsMarried()) {
cout << Name() << " is already married!" << endl;
return false;
}

if(Age() < 18) {


cout << Name() << " is too young to marry!" << endl;
return false;
}

return true;
}

void Person::Marry(Person& fiancee)


{
if(CanMarry() && fiancee.CanMarry()) {
if((IsMale() && fiancee.IsFemale())
|| (IsFemale() && fiancee.IsMale())) {
spouse = &fiancee;
fiancee.spouse = this;
cout << "Ding dong bells!" << endl;
}
else
cout << "Unenlightened times. No inter-sex marriages allowed!" << endl;
}
}

void Person::Speak(ostream& os) const


{
os << "My name is " << Name() << endl;
os << "I am a ";
if(IsMale())
os << "male";
else
os << "female";
os << " aged " << Age() << endl;
os << "I am ";
if(IsMarried())
os << "married to " << spouse->Name() << endl;
else
os << "not married" << endl;
}

//---------------------------------------------------------------------------
// main test program

int main()
{
cout << "Create a person" << endl;
Person Andrew("Andrew", "Bond", true);
Andrew.Speak(cout);

cout << "Create a potential wife" << endl;


Person Jenny("Jenny", "Bond", false);
Introduction to the UML Page 24

Jenny.Speak(cout);

cout << "Live 25 great years" << endl;


for(unsigned int i = 0; i < 25; ++i) {
Andrew.CelebrateBirthday();
Jenny.CelebrateBirthday();
}
Andrew.Speak(cout);

cout << "Get married" << endl;


Andrew.Marry(Jenny);
Andrew.Speak(cout);

cout << "Live 15 miserable years" << endl;


for(unsigned int i = 0; i < 25; ++i) {
Andrew.CelebrateBirthday();
Jenny.CelebrateBirthday();
}
Andrew.Speak(cout);

cout << "About to return from main()" << endl;


return 0;
}
//---------------------------------------------------------------------------
// Revision history
// 1.00 29/01/01 AJB modified for Feb 2001 class
// 1.10 28/09/01 AJB modified for Sept 2001 class
//----------------------------------------------------------------------------
Introduction to the UML Page 25

Answers to the class exercises


Exercise 1: use case diagram
Identify the actors and use cases for a computerised version of the classic card game Pontoon.

uses
Deal card Deal hand
uses

extends extends
Twist

extends Shuffle deck

extends Deal
Stick

extends

Play

extends

Betting
Player
Dealer

extends extends extends

Collect lost
Place bet Pay won bets
bets

Anda mungkin juga menyukai