Visual Case
Tool - UML Tutorial
3.
The Class Diagram
The class diagram is core to object-oriented
design. It describes the types of objects in the
system and the static relationships between them.
Packages
Packages allow you to break up a large number
of objects into related groupings. In many
object oriented languages (such as Java), packages
are used to provide scope and division to classes
and interfaces. In the UML, packages serve a
similar, but broader purpose.

Any UML diagram in Visual Case can have packages
on them. Each package can contain any type
and any number of other UML diagrams, as well as
interfaces and classes.
Classes
The core element of the class
diagram is the class. In an object oriented
system, classes are used to represent entities
within the system; entities that often relate to
real world objects.

The Contact class above is an example of a
simple class that stores location information.
Classes are divided into three sections:
Top: The
name,
package and
stereotype are
shown in the upper section of the class. In
Visual Case, classes shown on a diagram that do
not belong to the same package as the diagram are
shown with their entire path name. You can
optionally assign a stereotype to a class.
Centre: The
centre section contains the attributes of the
class.
Bottom: In the
lower section are the
operations that can be performed
on the class.
On any Visual Case class diagram, you can
optionally shown and hide both the attribute and
operations sections of all the classes or
individual classes. This is useful as often
you will want your class diagrams to highlight
specific constructs of your system that
superfluous information only serves to clutter and
confuse.
Attributes
An attribute
is a property of a class. In the example
above, we are told that a Contact has an
address, a city, a province, a country and a
postal code. It is generally understood that
when implementing the class, functionality is
provided to set and retrieve the information
stored in attributes. Methods to set and
retrieve attribute data are often called
accessor methods
(also getting
and setting
methods) and need not be shown in your model as
they are usually inferred.
The format for attributes is:
visibility name: type = defaultValue
The visibility is as follows:
|
- |
Private |
|
+ |
Public |
|
# |
Protected |
|
~ |
Package |
In object oriented design, it is generally
preferred to keep most attributes private as the
accessor methods allow you to control access to
the data. The most common exception to this
preference are constants.
In addition to the name, visibility, datatype and
default value, Visual Case allows you to specify
the following properties for an attribute:
Array: you can
set an attribute to be treated as an array of
attributes; shown with square braces
[ ] beside the
name.
Static:
attributes that are static only exist once for all
instances of the class. In the example
above, if we set city to be static, any
time we used the Contact class the city
attribute would always have the same value.
Final: if
an attribute is declared final, it's value cannot be
changed. The attribute is a constant.
Operations
The operations
listed in a class represent the functions or tasks
that can be performed on the data in the class.

In the List class above, there is one
attribute (a private array of Objects) and three
operations.
The format for operations is:
visibility name (parameters): type
The format is very similar to that of the
attribute except with the removal of a default
value and the addition of parameters.
Parameters take the format:
direction name: type = default value
The direction can be one of in, out,
inout or it can be unspecified.
In Visual Case you can show and hide the parameter
list for a class or all classes on a diagram.
If the list is hidden and an operation has
parameters, three dots are shown (...) to indicate
that parameters exist, but are hidden.
Sometimes operations have numerous parameters that
need not be shown all the time.
Generalization
The generalization
link is used between two classes to show that a
class incorporates all of the attributes and
operations of another, but adds to them in some
way.

In the above diagram, we again see our Contact
class, only now with two child classes. We
can say that Client and Company
inherit,
generalize or
extend Contact. In each of
Client and Company all of the
attributes in Contact (address, city, etc.)
exist, but with more information added. In
the above situation Contact is said to be
the superclass
of Client and Company.
When using a generalization link, the child
classes have the option to
override the operations in the
parent class. That is, they can include an
operation that is defined in the superclass, but
define a new implementation for it.

Above, OntarioTaxCalculator redefines or
overrides the
implementation of the method in BasicTaxCalculator.
Essentially, the code is different but the
operation is called the same way.
Sometimes you may want to force children to
override methods in a parent class. In this
case you can define the methods in the superclass
as abstract.
If a class has abstract operations, the class
itself is considered abstract. Abstract
methods and classes are shown in italics.
Not all of the operations in an abstract class
have to be abstract.

The abstract operation calculateTaxes in
AbstractTaxCalculator must be implemented in
the child classes OntarioTaxCalculator and
NovaScotiaTaxCalculator. Since the
operations must be implemented, it is not
necessary to show them in the child classes,
however you may if you choose. The key is to
keep your diagrams as clear as possible. In
the above instance the diagram is simple and the
meaning clear, however with multiple levels of
inheritance and more attributes and operations,
you may wish to specify all of the methods that
are overriden.
Interfaces
Many object oriented programming languages do not
allow for multiple inheritance. The
interface is
used to solve the limitations posed by this.
For example, in the earlier class diagram
Client and Company both generalize
Contact but one or the other child classes may
have something in common with a third class that
we do not want to duplicate in multiple classes.

The interface Sortable, is used in the
above example to show that both Company and
Product implement the sort
operation. We can say that Company
and Product
implement Sortable or that they
are Sortable. Because Product already
generalizes Contact, we could not also
allow it to generalize Sortable.
Instead, we made Sortable an interface and
added a realization
link to show the implementation.
Interfaces are very similar to abstract classes with the
exception that they do not have any attributes.
As well, unlike a class, all of the operations in an
interface have no implementation. The child
classes Company and Product are
forced to implement the sort operation in its entirety.
Associations
Classes can also contain references to each other.
The Company class has two attributes that
reference the Client class.

Although this is perfectly correct, it is
sometimes more expressive to show the attributes
as associations.

The above two associations have the same meaning
as the attributes in the old version of the
Contact class.
The first association (the top one) represents the
old contactPerson attribute. There is
one contact person in a single Company.
The multiplicity
of the association is one to one meaning that for
every Companythere is one and only one
contactPerson and for each contactPerson
there is one Company. In the bottom
association there are zero or many employees for
each company. Multiplicities can be anything
you specify. Some examples are shown:
|
0 |
zero |
|
1 |
one |
|
1..* |
one or many |
|
1..2, 10..* |
one, two or
ten and above but not three through
nine |
The arrows at the end of the associations
represent their
navigability. In the above
examples, the Company references Clients,
but the Client class does not have any
knowledge of the Company. You can set
the navigability on either, neither or both ends
of your associations. If there is no
navigability shown then the navigability is
unspecified.
Aggregation and
Composition

The above example shows an
aggregation association and a
composition
association.
The composition
association is represented by the solid diamond.
It is said that ProductGroup is
composed of
Products. This means that if a
ProductGroup is destroyed, the Products
within the group are destroyed as well.
The aggregation
association is represented by the hollow diamond.
PurchaseOrder is an
aggregate of Products.
If a PurchaseOrder is destroyed, the
Products still exist.
If you have trouble remembering the difference
between composition and aggregation, just think of
the alphabet. Composition means destroy and
the letters 'c' and 'd' are next to each other.
Dependencies
A dependency
exists between two elements if changes to one will
affect the other. If for example, a class
calls an operation in another class, then a
dependency exists between the two. If you
change the operation, than the dependent class
will have to change as well. When designing
your system, the goal is to minimize dependencies.

To help clarify the dependencies in your design,
you may wish to draw a
Package Diagram. A package
diagram is essentially a class diagram with only
packages and dependencies showing.
Dependencies can exist between any components in
the UML however at the highest level, dependencies
will exist between packages. Within a
package, the dependencies may be too numerous to
specify. That is not to say that numerous
dependencies are okay. Even within a package
you want to limit the dependencies, however
between packages in particular you should be
strict about the number of dependencies that
exist. In general, the fewer the
dependencies the more
scaleable and
maintainable your system will be.
Putting it all Together
Class diagrams really are the core of most object
oriented design so you will likely find yourself
using them all the time. Fortunately class
diagrams closely relate to the most object
oriented languages, so the basics (classes,
operations, attributes, generalizations, etc.)
should be fairly easy to grasp. Start with
what you know and then move on.
The most important thing about design is to not
let it bog you down with detail. It is
better to have a few clear diagrams than many,
overly complex diagrams. Previously we saw
the AbstractTaxCalculator that was
generalized by OntarioTaxCalculator and
NovaScotiaTaxCalculator. If we tried to
create a diagram with all ten Canadian provinces
and the three territories we would have a huge
complex mess. If we were designing a tax
system for the United States and we tried to show
all of the states, we would be in even more
trouble. It is more clear, and just as
expressive to show two or three child classes and
add a note to the diagram the explains that the
other provinces and territories are implemented in
the same way.
Keeping your designs simple will allow you to be
more productive as well as making your designs far
more understandable and useable. Also, as
the system is implemented and upgraded, you'll
want to keep your design in synch with your
implementation. This will be far easier with
a simple design of the key concepts of the system.
Page 1:
Introduction
Page 2:
Use Case Diagrams
Page 3:
Class Diagrams
Page 4:
Interaction
Diagrams - Sequence & Collaboration
Page 5:
Activity & State Diagrams
Page 6:
Implementation Diagrams - Component & Deployment
Page 7:
Summary & Further
Reading
Visual
CaseTM is a trademark or registered trademark
of Artiso Corp. Canada.
Microsoft, Windows, SQL
Server, VB, Visual Basic and Access are registered trademarks of
Microsoft Corporation.
Oracle is a registered
trademark of Oracle Corporation.
Unified
Modeling Language and UML are trademarks of Object Management Group
Inc. in the U.S. and other countries. Other brands and their products
are trademarks or registered trademarks of their respective holders
and should be noted
as such.
This
site is best viewed at a resolution of 800 by 600 using Internet
Explorer 5. |