UML类图关系
《The Unified Modeling Language User Guide;2nd 》的对于几种关系的描述
In the UML, the ways that things can connect to one another, either logically or physically, are modeled as relationships. In object-oriented modeling, there are three kinds of relationships that are most important: dependencies, generalizations, and associations.
Dependencies are using relationships. For example, pipes depend on the water heater to heat the water they carry.
Associations are structural relationships among instances. For example, rooms consist of walls and other things; walls themselves may have embedded doors and windows; pipes may pass through walls.
Generalizations connect generalized classes to more-specialized ones in what is known as subclass/superclass or child/parent relationships. For example, a picture window is a kind of window with very large, fixed panes; a patio window is a kind of window with panes that open side to side.
These three kinds of relationships cover most of the important ways in which things collaborate with one another. Not surprisingly, they also map well to the ways that are provided by most object-oriented programming languages to connect objects.
Dependencies
A dependency is a relationship that states that one thing (for example, class Window) uses the information and services of another thing (for example, class Event), but not necessarily the reverse. Graphically, a dependency is rendered as a dashed directed line, directed to the thing being depended on. Choose dependencies when you want to show one thing using another.
Most often, you will use dependencies between classes to show that one class uses operations from another class or it uses variables or arguments typed by the other class; see Figure 5-2. This is very much a using relationshipif the used class changes, the operation of the other class may be affected as well, because the used class may now present a different interface or behavior. In the UML you can also create dependencies among many other things, especially notes and packages.
Figure 5-2. Dependencies
Note
A dependency can have a name, although names are rarely needed unless you have a model with many dependencies and you need to refer to or distinguish among dependencies. More commonly, you'll use stereotypes to distinguish different flavors of dependencies.(Chapter 5)
A dependency is a using relationship, specifying that a change in the specification of one thing (for example, class SetTopController) may affect another thing that uses it (for example, class ChannelIterator), but not the reverse. (Chapter 10)
Generalizations
A generalization is a relationship between a general kind of thing (called the superclass or parent) and a more specific kind of thing (called the subclass or child). Generalization is sometimes called an "is-a-kind-of" relationship: one thing (like the class BayWindow) is-a-kind-of a more general thing (for example, the class Window). An objects of the child class may be used for a variable or parameter typed by the parent, but not the reverse. In other words, generalization means that the child is substitutable for a declaration of the parent. A child inherits the properties of its parents, especially their attributes and operations. Oftenbut not alwaysthe child has attributes and operations in addition to those found in its parents. An implementation of an operation in a child overrides an implementation of the same operation of the parent; this is known as polymorphism. To be the same, two operations must have the same signature (same name and parameters). Graphically, generalization is rendered as a solid directed line with a large unfilled triangular arrowhead, pointing to the parent, as shown in Figure 5-3. Use generalizations when you want to show parent/child relationships.
Figure 5-3. Generalization
A class may have zero, one, or more parents. A
class that has no parents and one or more children is called a root class or a
base class. A class that has no children is called a leaf class. A class that
has exactly one parent is said to use single inheritance; a class with more than
one parent is said to use multiple inheritance.
Most often, you will use generalizations among
classes and interfaces to show inheritance relationships. In the UML, you can
also create generalizations among other kinds of classifiers, such as
nodes.
Note
A generalization with a name indicates a
decomposition of the subclasses of a superclass on a particular aspect, called a
generalization set. Multiple generalization sets are orthogonal; the superclass
is intended to be specialized using multiple inheritance to select one subclass
from each generalization set. This is an advanced topic that we do not cover in
this book.(Chapter 5)
Associations
An association
is a structural relationship
that specifies that objects of one thing are connected to objects of
another. Given an association connecting two classes, you can relate
objects of one class to objects of the other class. It's quite legal to have
both ends of an association circle back to the same class. This means that,
given an object of the class, you can link to other objects of the same class.
An association that connects exactly two classes is called a binary association.
Although it's not as common, you can have associations that connect more than
two classes; these are called n-ary
associations. Graphically, an association is rendered as a solid line
connecting the same or different classes. Use associations when you want to show
structural relationships.
Associations and
dependencies (but not generalization relationships) may be reflective, as
discussed in Chapter 10.
|
Beyond this basic form, there are four
adornments that apply to associations.
Name
An association can have a name, and you use that
name to describe the nature of the relationship. So that there is no ambiguity
about its meaning, you can give a direction to the name by providing a direction
triangle that points in the direction you intend to read the name, as shown in
Figure 5-4.
Figure 5-4. Association
Names
Note
Although an association may have a name, you
typically don't need to include one if you explicitly provide end names for the
association. If you have more than one association connecting the same classes,
it is necessary to use either association names or association end names to
distinguish them. If an association has more than one end on the same class, it
is necessary to use association end names to distinguish the ends. If there is
only one association between a pair of classes, some modelers omit the names,
but it is better to provide them to make the purpose of the association
clear.(Chapter 5)
Aggregation
A plain association between two classes
represents a structural relationship between peers, meaning that both classes
are conceptually at the same level, no one more important than the
other. Sometimes you will want to model a "whole/part" relationship, in
which one class represents a larger thing (the "whole"), which consists of
smaller things (the "parts"). This kind of relationship is called aggregation,
which represents a "has-a"
relationship, meaning that an object of the whole has objects of the part. Aggregation is really just a special kind of association and is specified by adorning a plain association with
an unfilled diamond at the whole end, as shown in Figure 5-7.
Figure 5-7. Aggregation
Note
The meaning of this simple form of aggregation
is entirely conceptual. The open diamond distinguishes the "whole" from the
"part," no more, no less. This means that simple aggregation does not change the
meaning of navigation across the association between the whole and its parts,
nor does it link the lifetimes of the whole and its parts. See the section on
composition in Chapter 10 for a tighter form of
aggregation.(Chapter 5)
Realizations
A realization
is a semantic relationship between classifiers in which one classifier specifies
a contract that another classifier
guarantees to carry out. Graphically, a realization is rendered as a
dashed directed line with a large open arrowhead pointing to the classifier that
specifies the contract.
Realization is different enough from dependency,
generalization, and association relationships that it is treated as a separate kind of relationship. Semantically, realization
is somewhat of a cross between dependency and generalization, and its notation
is a combination of the notation for dependency and generalization. You'll use
realization in two circumstances: in the context of interfaces and in the
context of collaborations.
Interfaces are
discussed in Chapter 11; classes are discussed in Chapters 4 and components are discussed in
Chapter 15; the five views of an architecture are
discussed in Chapter 2.
|
Most of the time you'll use realization to
specify the relationship between an interface and the class or component that
provides an operation or service for it. An interface is a collection of
operations that are used to specify a service of a class or a component.
Therefore, an interface specifies a contract that a class or component must
carry out. An interface may be realized by many such classes or components, and
a class or component may realize many interfaces. Perhaps the most interesting
thing about interfaces is that they let you separate the specification of a
contract (the interface itself) from its implementation (by a class or a
component). Furthermore, interfaces span the logical and physical parts of a
system's architecture. For example, as Figure 10-8 shows, a class (such as
AccountBusinessRules in an order entry system) in a system's design
view might realize a given interface (such as IRuleAgent). That same
interface (IRuleAgent) might also be realized by a component (such as
acctrule.dll) in the system's implementation view. Note that you can
represent realization in two ways: in the canonical form (using the
interface stereotype and the dashed directed line with a large open
arrowhead) and in an elided form (using the interface lollipop notation for a
provided interface).
Figure 10-8. Realization of an
Interface
You'll also use realization to specify the
relationship between a use case and the collaboration that realizes that use
case, as Figure 10-9 shows. In this circumstance, you'll
almost always use the dashed arrow form of realization.
Figure 10-9. Realization of a Use
Case
Note
When a class or a component realizes an
interface, it means that clients can rely on the class or component to
faithfully carry out the behavior specified by the interface. That means the
class or component implements all the operations of the interface, responds to
all its signals, and in all ways follows the protocol established by the
interface for clients who use those operations or send those signals.(Chapter
10)
Composition
Aggregation turns out to be a simple concept
with some fairly deep semantics. Simple aggregation is entirely conceptual and
does nothing more than distinguish a "whole" from a "part." Simple aggregation does not change the meaning of navigation
across the association between the whole and its parts, nor does it link the
lifetimes of the whole and its parts.
However, there is a variation of simple
aggregation composition that does add some important semantics. Composition is a form of aggregation, with strong ownership
and coincident lifetime as part of the whole. Parts with non-fixed
multiplicity may be created after the composite itself, but once created they live and die with it. Such
parts can also be explicitly removed before the death of the
composite.
An attribute is
essentially a shorthand for composition; attributes are discussed in Chapters 4 and 9.
|
This means that, in a composite aggregation, an
object may be a part of only one composite at a time. For example, in a
windowing system, a Frame belongs to exactly one Window. This
is in contrast to simple aggregation, in which a part may be shared by several
wholes. For example, in the model of a house, a Wall may be a part of
one or more Room objects.
In addition, in a composite aggregation the
whole is responsible for the disposition of its parts, which means that the
composite must manage the creation and destruction of its parts. For example,
when you create a Frame in a windowing system, you must attach it to an
enclosing Window. Similarly, when you destroy the Window, the
Window object must in turn destroy its Frame
parts.
As Figure 10-6 shows, composition is really just a
special kind of association and is specified by adorning a plain association
with a filled diamond at the whole end.
Figure 10-6. Composition
Note
Alternately, you can show composition by using a
structured class and nesting the symbols of the parts within the symbol of the
composite. This form is most useful when you want to emphasize the relationships
among the parts that apply only in the context of the whole.(Chapter
10)