UML
Walkthrough
UML
Views
There is no sharp line between the various
concepts and constructs in UML, but, for convenience, we divide them into
several views. A view is simply a subset of UML modeling constructs that
represents one aspect of a system. The division into different views is
somewhat arbitrary, but we hope it is intuitive. One or two kinds of diagrams
provide a visual notation for the concepts in each view. At the top level,
views can be divided into three areas: structural classification, dynamic
behavior, and model management. Structural classification describes the things
in the system and their relationships to other things. Classifiers include
classes, use cases, components, and nodes. Classifiers provide the basis on top
of which dynamic behavior is built. Classification views include the static
view, use case view, and implementation view.
Dynamic behavior describes the behavior of a
system over time. Behavior can be described as a series of changes to snapshots
of the system drawn from the static view. Dynamic behavior views include the
state machine view, activity view, and interaction view.
Model management describes the organization
of the models themselves into hierarchical units. The package is the generic
organizational unit for models. Special packages include models and subsystems.
The model management view crosses the other views and organizes them for
development work and configuration control. UML also contains several
constructs intended to provide a limited but useful extensibility capability.
These constructs include constraints, stereotypes, and tagged values. These
constructs are applicable to elements of all views. Table 3-1 shows the UML
views and the diagrams that display them, as well as the main concepts relevant
to each view. This table should not be taken as a rigid set of rules but merely
as a guide to normal usage, as mixing of views is permitted.
Table 3-1: UML Views and Diagrams
Major Area
|
View
|
Diagrams
|
Main Concepts
|
Structural
|
static view
|
class diagram
|
class, association, generalization, dependency,
realization, interface
|
use case view
|
use case diagram
|
use case, actor, association, extend, include, use
case generalization
|
|
implementation view
|
component diagram
|
component, interface, dependency, realization
|
|
deployment view
|
deployment diagram
|
node, component, dependency, location
|
|
dynamic
|
state machine view
|
statechart diagram
|
state, event, transition, action
|
activity view
|
activity diagram
|
state, activity, completion transition, fork, join
|
|
interaction view
|
sequence diagram
|
interaction, object, message, activation
|
|
collaboration diagram
|
collaboration, interaction, collaboration role,
message
|
||
model management
|
model management view
|
class diagram
|
package, subsystem, model
|
extensibility
|
all
|
all
|
constraint, stereotype, tagged values
|
Static View
The static view models concepts in the application
domain, as well as internal concepts invented as part of the implementation
of an application. This view is static because it does not describe the
time-dependent behavior of the system, which is described in other views.
The main constituents of the static view are classes and their relationships:
association, generalization, and various kinds of dependency, such as
realization and usage. A class is the description of a concept from the
application domain or the application solution. Classes are the center around
which the class view is organized; other elements are owned by or attached to
class es .
Classes are drawn as rectangles. Lists of attributes
and operations are shown in separate compartments.
The compartments can be suppressed when full detail is not needed. A class may
appear on several diagrams. Its attributes and operations are often suppressed
on all but one diagram.
Relationships among classes are drawn as paths
connecting class rectangles. The different kinds of relationships are
distinguished by line texture and by adornments on the paths or their ends.
Figure 3-1
shows a class diagram from the box office application. This diagram contains
part of a ticket-selling domain model. It shows several important classes, such
as Customer, Reservation, Ticket, and Performance. Customers may have many
reservations, but each reservation is made by one customer. Reservations are of
two kinds: subscription series and individual reservations. Both reserve
tickets: in one case, only one ticket; in the other case, several tickets.
Every ticket is part of a subscription series or an individual reservation, but
not both. Every performance has many tickets available, each with a unique seat
number. A performance can be identified by a show, date, and time.
Classes can be described at various levels of
precision and concreteness. In the early stages of design, the model captures
the more logical aspects of the problem. In the later stages, the model also
captures design decisions and implementation details. Most of the views have a
similar evolutionary quality.
attributes
class scope operation
association 1
owner rolename
|
* purchased
1 show
0..1 constraint 0..1 multiplicities
{xor}
|
|
1..∗
3..6 1
∗ 1
qualifier
operation
Figure 3-1. Class diagram
Use Case View
The use case view models the functionality of the
system as perceived by outside users, called actors. A use case is a coherent
unit of functionality expressed as a transaction among actors and the system.
The purpose of the use case view is to list the actors and use cases and show
which actors participate in each use case.
Figure 3-2
shows a use case diagram for the box office example. Actors include the clerk,
supervisor, and kiosk. The kiosk is another system that accepts orders from a
customer. The customer is not an actor in the box office application because
the customer is not directly connected to the application. Use cases include
buying tickets through the kiosk or the clerk, buying subscriptions (only
through the clerk), and surveying total sales (at the request of the supervisor).Buying
tickets and buying subscriptions include a common fragment—that is, making
charges to the credit card service. (A complete description of a box office
system would involve a number of other use cases, such as exchanging tickets
and checking availability.)
Use cases can
also be described at various levels of detail. They can be factored and
described in terms of other, simpler use cases. A use case is implemented as a
collaboration in the interaction view.
Interaction View
The interaction view describes sequences of message exchanges among
roles that implement behavior of a system. A classifier role is the description
of an object that plays a particular part within an interaction, as
distinguished from other objects of the same class. This view provides a
holistic view of behavior in a system— that is, it shows the flow of control
across many objects. The interaction view is displayed in two diagrams focused
on different aspects: sequence diagrams and collaboration diagrams.
Sequence diagram
A sequence
diagram shows a set of messages arranged in time sequence. Each classifier role
is shown as a lifeline—that is, a vertical line that represents the role over
time through the entire interaction. Messages are shown as arrows between
lifelines. A sequence diagram can show a scenario—that is, an individual
history of a transaction.
One use of a
sequence diagram is to show the behavior sequence of a use case. When the
behavior is implemented, each message on a sequence diagram corresponds to an
operation on a class or an event trigger on a transition in a state machine.
Figure 3-3 shows a sequence diagram for the buy
tickets use case. This use case is initiated by the customer at the kiosk
communicating with the box office. The steps for the make charges use case are
included within the sequence, which involves communication with both the kiosk
and the credit card service. This sequence diagram is at an early stage of
development and does not show the full details of the user interface. For
example, the exact form of the seat list and the mechanism of specifying seats
must still be determined, but the essential communication of the interaction
has been specified by the use case.
Collaboration diagram
A collaboration
models the objects and links that are meaningful within an interaction. The
objects and links are meaningful only in the context provided by the
interaction. A classifier role describes an object and an association role
describes a link within a collaboration. A collaboration diagram shows the
roles in the interaction as a geometric arrangement (Figure 3-4). The messages
are shown as arrows attached to the relationship lines connecting classifier
roles. The sequence of messages is indicated by sequence numbers prepended to
message descriptions.
One use of a collaboration diagram is to show the
implementation of an operation. The collaboration shows the parameters and
local variables of the operation, as well as more permanent associations. When
the behavior is implemented, the message sequencing corresponds to the nested
calling structure and signal passing of the program.
Figure 3-4
shows a collaboration diagram for the reserve tickets interaction. The request
arrives from the kiosk and is used to find the database for the particular
performance from the set of all performances. The pointer db that is returned
to the ticketSeller object represents a local transient link to a performance
database that is maintained during the interaction and then discarded. The
ticket seller requests a number of seats to the performance; a selection of
seats in various price ranges is found, temporarily locked, and returned to the
kiosk for the customer’s selection. When the customer makes a selection from
the list of seats, the selected seats are claimed and the rest are unlocked.
Both sequence diagrams and collaboration diagrams show
interactions, but they emphasize different aspects. A sequence diagram shows
time sequence as a geometric dimension, but the relationships among
roles are implicit. A collaboration diagram shows the relationships
among roles geometrically and relates messages to the relationships,
but time sequences are less clear because they are implied by the sequence
numbers.
State Machine View
A state machine models the possible life histories of
an object of a class. A state machine contains states connected by transitions.
Each state models a period of time during the life of an object during which it
satisfies certain conditions. When an event occurs, it may cause the firing of
a transition that takes the object to a new state. When a transition fires, an
action attached to the transition may be executed. State machines are shown as
statechart diagrams.
Figure 3-5
shows a statechart diagram for the history of a ticket to a performance. The
initial state of a ticket (shown by the black dot) is the Available state.
Before the season starts, seats for season subscribers are assigned. Individual
tickets purchased interactively are first locked while the customer makes a
selection. After that, they are either sold or unlocked if they are not chosen.
If the customer takes too long to make a selection, the transaction times out
and the seat is released. Seats sold to season subscribers may be exchanged for
other performances, in which case they become available again.
State machines
may be used to describe user interfaces, device controllers, and other reactive
subsystems. They may also be used to describe passive objects that go through
several qualitatively distinct phases during their lifetime, each of which has
its own special behavior.
Activity View
An activity graph is a variant of a state machine. An activity state represents an activity: a
workflow step or the execution of an operation. An activity graph describes
both sequential and concurrent groups of activities. Activity graphs are shown
on activity diagrams.
Figure 3-6 shows an activity diagram for the box
office. This diagram shows the activities involved in mounting a show. Arrows
show sequential dependencies—for example, shows must be picked before they are
scheduled. Heavy bars show forks or joins of control. For example, after the
show is scheduled, the theater can begin to publicize it, buy scripts, hire
artists, build sets, design lighting, and make costumes, all concurrently.
Before rehearsal can begin, however, the scripts must be ordered and the artist
must be hired.
This example shows an activity diagram the purpose of
which is to model the real-world workflows of a human organization. Such business
modeling is a major purpose of activity diagrams, but activity diagrams can
also be used for modeling software activities. An activity diagram is helpful
in understanding the high-level execution behavior of a system, without
getting involved in the internal details of message passing required by a
collaboration diagram.
The input and output parameters of an action can be
shown using flow relationships connecting the action and an object flow state.
Figure 3-5. Statechart diagram
Physical Views
The previous
views model the concepts in the application from a logical viewpoint. The
physical views model the implementation structure of the application itself,
such as its organization into components and its deployment onto run-time
nodes. These views provide an opportunity to map classes onto implementation components
and nodes. There are two physical views: the implementation view and the
deployment view.
The implementation view models the
components in a system—as well as the dependencies among components so that the
impact of a proposed change can be assessed. It also models the assignment of
classes and other model elements to components.
The implementation view is displayed on component
diagrams. Figure 3-7 shows a component diagram for the box office system. There
are three user interfaces: one each for customers using a kiosk, clerks using
the on-line reservation system, and supervisors making queries about ticket
sales. There is a ticket seller component that sequentializes requests from
both kiosks and clerks; a component that processes credit card charges; and the
database containing the ticket information. The component diagram shows the
kinds of components in the system; a particular configuration of the
application may have more than one copy of a component.
A small circle
with a name is an interface. A solid line from a component to an interface
indicates that the component provides the services listed in the interface. A dashed
arrow from a component to an interface indicates that the component requires
the services provided by the interface. For example, subscription sales and
group sales are both provided by the ticket seller component; subscription
sales are accessible from both kiosks and clerks, but group sales are only
accessible from a clerk.
The deployment
view represents the arrangement of run-time
component instances on node instances. A node is a run-time resource, such as a
computer, device, or memory. This view permits the consequences of distribution
and resource allocation to be assessed.
The deployment view is displayed on deployment
diagrams. Figure 3-8 shows a descriptor-level deployment diagram for the box
office system. This diagram shows the kinds of nodes in the system
and the kinds of components they hold. A node is shown as a cube symbol.
Figure 3-9 shows an instance-level deployment diagram
for the box office system. The diagram shows the individual nodes and their
links in a particular version of the system. The information in this model is
consistent with the descriptor-level information in Figure 3-8.
Model Management View
The model
management view models the organization of the model itself. A model
comprises a set of packages that hold model elements, such as classes,
state machines, and use cases. Packages may contain other packages:
therefore, a model designates a root package that indirectly contains all the
contents of the model. Packages are units for manipulating the
contents of a model, as well as units for access control and configuration
control. Every model element is owned by one package or one other element.
Figure 3-10. Packages
There
may be several models of a system from various viewpoints—for example, an
analysis model as well as a design model. A model is shown as a special kind of
package. A subsystem is another special package. It represents a
portion of a system, that can be implemented as a distinct
component. Model management information is usually shown on class diagrams.
Figure 3-10 shows the breakdown of the entire theater system into packages and
their dependency relationships. The box office subsystem includes the previous
examples in this chapter; the full system also includes theater operations and
planning subsystems. Each subsystem consists of several packages.
Extensibility Constructs UML includes three main extensibility constructs: constraints,
stereotypes, and tagged values. A constraint is a textual statement of a
semantic relationship expressed in some formal language or in natural language.
A stereotype is a new kind of model element devised by the modeler and based on
an existing kind of model element. A tagged value is a named piece of
information attached to any model element.
These
constructs permit many kinds of extensions to UML without requiring changes
to the basic UML metamodel itself. They may be used to create
tailored versions of the UML for an application area.
Figure 3-11
shows examples of constraints, stereotypes, and tagged values. The constraint
on class Show ensures that the names of shows are unique. Constraints statements can be expressed in a text language but which
are not directly supported by UML constructs.
The stereotype on component TicketDB indicates that
the component is a database, which permits the interfaces supported by the
component to be omitted as they are the interfaces supported by all databases. Modelers
can add new stereotypes to represent special elements.
A set of constraints, tagged values,
or code generation properties can be attached to a stereotype. A modeler
can define an icon for a given stereotype name as a visual aid, as shown in
the diagram.
The tagged
values on package Scheduling show that Frank Martin is responsible for
finishing it before the end of the millennium. Any information can be attached to a model element
as a tagged value by the modeler. Text
values are especially useful for project management information and for code
generation parameters. Most tagged values would be stored as popup information
within an editing tool and would not usually be displayed on printed pictures.
Static View
Overview
Dynamic views require the static view to
describe the things that interact dynamically—you can’t say how something
interacts without first saying what is interacting. The static view is the
foundation on which the other views are built. The key elements in the static
view are classifiers and their relationships.
Classifiers A
classifier is a discrete concept in the model, having identity, state, behavior,
and relationships. Kinds of classifiers include class, interface, and
data type.
Class. A class represents a
discrete concept within the application being modeled—a physical thing (such as
an airplane), a business thing (such as an order), a logical thing (such as a
broadcasting schedule), an application thing (such as a cancel button), a
computer thing (such as a hash table), or a behavioral thing (such as a task). A
class is the descriptor for a set of objects with similar structure,
behavior, and relationships. All attributes and operations are attached to
classes or other classifiers. Classes are the foci around which
object-oriented systems are organized.
An object
is a discrete entity with identity, state, and invocable behavior. Objects are the
individual pieces out of which a run-time system is constructed;
A class defines a set of objects that have
state and behavior. State is described by attributes and associations.
Attributes are generally used for pure data values without identity, such as
numbers and strings, and associations are used for connections among objects
with identity. Individual pieces of invocable behavior are described by
operations; a method is the implementation of an operation. The lifetime
history of an object is described by a state machine attached to a class
notation for a class is a rectangle with
compartments for the name of the class, attributes, and operations, as shown in
Figure 4-1. A
set of
classes may use the generalization relationship and the inheritance mechanism
built on it to share common pieces of state and behavior description.
Generalization relates more specific classes (subclasses) to more general
classes (superclasses) that contain properties common to several subclasses. A
class may have zero or more parents (superclasses) and zero or more children
(subclasses). A class inherits state and behavior descriptions from its parents
and other ancestors, and it defines state and behavior descriptions that its
children and other descendants inherit.
The
class has a visibility with respect to its container; the visibility specifies
how it may be used by other classes outside the container.
A class has a multiplicity that specifies how
many instances of it may exist. Most often, this is many (zero or more, without
explicit limit), but singleton classes occur for which a single instance exists
during execution. Interface.
An interface is the description of behavior of
objects without giving their implementation or state; an interface contains
operations but not attributes, and it does not have outgoing associations that
are visible to it. One or more classes or components may realize an interface,
and each class implements the operations found in the interface
Data type.
A data type
is the description of primitive values that lack identity (independent
existence and the possibility of side effects). Data types include numbers,
strings, and enumerated values. Data types are passed by value and are
immutable entities. A data type has no attributes but may have operations.
Operations do not modify data values, but they may return data values as
results
Levels of meaning.
Classes can exist at several levels of meaning
in a model, including the analysis, design, and implementation levels.
An
analysis-level class represents a logical concept in the application domain
or in the application itself. The analysis model should be a minimal
representation of the system being modeled, sufficient to capture the essential
logic of the system without getting into issues of performance or construction.
When
representing a high-level design, concepts such as localization of state
to particular classes, efficiency of navigating among objects, separation of
external behavior and internal implementation, and specification of the precise
operations are relevant to a class. A design-level class represents the
decision to package state information and the operations on it into a discrete
unit. It captures the key design decision, the localization of information and
functionality to objects.
Design-level classes contain both real-world
content and computer system content.
Finally,
when representing programming-language code, the form of a class closely matches
the chosen programming language, and some abilities of a general class may be
forgone if they have no direct implementation in the language.
An implementation-level class maps directly
into programming-language code. The same system can contain more than one level
of class. An implementation class represents the declaration of a class as
found in a particular programming language. It captures the exact form of a
class, as needed by the language.
In many cases, however, analysis, design, and
implementation information can be nested into a single class.
Relationships
Relationships among classifiers are association, generalization, flow, and various kinds of dependency, including realization and usage
The association relationship
describes semantic connections among individual objects of given classes. Associations provide the connections with which objects of different classes can interact.
The generalization relationship relates general descriptions of parent classifiers (superclasses) to more specialized child classifiers (subclasses). Generalization facilitates the description of classifiers out of incremental declaration pieces, each of which adds to the description inherited from its ancestors.
The inheritance mechanism constructs complete descriptions of classifiers from incremental descriptions using generalization relationships. Generalization and inheritance permit different classifiers to share the attributes, operations, and relationships that they have in common, without repetition.
The realization relationship relates a specification to an implementation. An interface is a specification of behavior without implementation; a class includes implementation structure. One or more classes may realize an interface, and each class implements the operations found in the interface.
The flow relationship relates two versions of an object at successive times. It represents a transformation of the value, state, or location of an object. The flow relationship may connect classifier roles in an interaction.
Varieties of flow are become (two versions of the same object) and copy (a new object created from an existing object).
The dependency relationship relates classes whose behavior or implementation affects other classes. There are several kinds of dependency in addition to realization, including trace (a loose connection among elements in different models), re- finement (a mapping between two levels of meaning), usage (a requirement for the presence of another element within a single model), and binding (the assignment of values to template parameters). Usage dependency is frequently used to represent implementation relationships, such as code-level relationships.
Dependency is particularly useful when summarized on model organization units, such as packages, on which it shows the architectural structure of a system. Compilation constraints can be shown by dependencies, for example.
Associations
An association describes discrete connections among objects or other instances in a system. An association relates an ordered list (tuple) of two or more classifiers, with repetitions permitted.
The most common kind of association is a binary association between a pair of classifiers. An instance of an association is a link. A link comprises a tuple (an ordered list) of objects, each drawn from its corresponding class. A binary link comprises a pair of objects.
Associations carry information about relationships among objects in a system. As a system executes, links among objects are created and destroyed.
Associations are the “glue” that ties a system together. Without associations, there are nothing but isolated classes that don’t work together.
A single object may be associated with itself if the same class appears more than once in an association. If the same class appears twice in an association, the two instances do not have to be the same object, and usually they are not.
Each connection of an association to a class is called an association end. Most information about an association is attached to one of its ends. Association ends can have names (rolenames) and visibility.
The most important property they have is multiplicity—how many instances of one class can be related to one instance of the other class.
The notation for a binary association is a line or path connecting the participating classes. The association name is placed along the line with the rolename and multiplicity at each end, as shown in Figure 4-2. An association can also have attributes of its own, in which case it is both an association and a class—an association class (see Figure 4-3).
If an association attribute is unique within a set of related objects, then it is a qualifier (see Figure 4-4). A qualifier is a value that selects a unique object from the set of related objects across an association. Lookup tables and arrays may be modeled as quali- fied associations. Qualifiers are important for modeling names and identification codes. Qualifiers also model indexes in a design model.
A navigable association at the design stage represents state information available to a class, but it can be mapped into programming-language code in various ways. The implementation can be a pointer, a container class embedded in a class, or even a completely separate table object. Other kinds of design properties include visibility and changeability of links. Figure 4-5 shows some design properties of associations.
Aggregation and composition.
An aggregation is an association that represents a part-whole relationship. It is shown by a hollow-diamond adornment on the end of the path attached to the aggregate class. A composition is a stronger form of association in which the composite has sole responsibility for managing its parts— such as their allocation and deallocation. It is shown by a filled-diamond adornment on the composite end. There is a separate association between each class representing a part and the class representing the whole, but for convenience the paths attached to the whole may be joined together so that the entire set of associations is drawn as a tree. Figure 4-6 shows an aggregate and a composite. Links. An instance of an association is a link. A link is an ordered list of object references, each of which must be an instance of the corresponding class in the Figure 4-5. Design properties of association Person Address address 1 TransactionEntry history ∗ {ordered, addOnly} 1 navigability direction ordering property changeability constraint 50 Part 2 • UML Concepts association or an instance of a descendant of the class. The links in a system constitute part of the system state. Links do not exist independently of objects; they take their identity from the objects they relate (in database terms, the list of objects is the key for the link). Conceptually, an association is distinct from the classes that it relates. In practice, associations are often implemented using pointers in the participating classes, but they can be implemented as container objects separate from the classes they connect. Bidirectionality. The different ends of an association are distinguishable, even if two of them involve the same class. This simply means that different objects of the same class can be related. Because the ends are distinguishable, an association is not symmetric (except in special cases); the ends cannot be interchanged. This is only common sense in ordinary discourse; the subject and the object of a verb are not interchangeable. An association is sometimes said to be bidirectional. This means that the logical relationships work both ways. This statement is frequently misunderstood, even by some methodologists. It does not mean that each class “knows” the other class, or that, in an implementation, it is possible to access each class from the other. It simply means that any logical relationship has an inverse, whether or not the inverse is easy to compute. To assert the ability to traverse an association in one direction but not the other as a design decision, associations can be marked with navigability. Why is the basic model relational, rather than the pointer model prevalent in programming languages? The reason is that a model attempts to capture the intent behind an implementation. If a relationship between two classes is modeled as a pair of pointers, the pointers are nevertheless related. The association approach acknowledges that relationships are meaningful in both directions, regardless of how they are implemented. It is simple to convert an association into a pair of pointers for implementation, but very difficult to recognize that two pointers are inverses of each other unless this fact is part of the model. Figure 4-6. Aggregation and composition Order CustomerInfo LineItem composite parts 1 ∗ 1 Subscription Performance ∗ ∗ 1 parts aggregate Chapter 4 • Static View 51 Generalization The generalization relationship is a taxonomic relationship between a more general description and a more specific description that builds on it and extends it. The more specific description is fully consistent with the more general one (it has all its properties, members, and relationships) and may contain additional information. For example, a mortgage is a more specific kind of loan. A mortgage keeps the basic characteristics of a loan but adds additional characteristics, such as a house as security for the loan. The more general description is called the parent; an element in the transitive closure is an ancestor. The more specific description is called the child; an element in the transitive closure is a descendant. In the example, Loan is the parent class and Mortgage is the child class. Generalization is used for classifiers (classes, interfaces, data types, use cases, actors, signals, and so on), packages, state machines, and other elements. For classes, the term superclass and subclass are used for parent and child. A generalization is drawn as an arrow from the child to the parent, with a large hollow triangle on the end connected to the parent (Figure 4-7). Several generalization relationships can be drawn as a tree with one arrowhead branching into several lines to the children. Purpose of generalization. Generalization has two purposes. The first is to define the conditions under which an instance of one class (or other element) can be used when a variable (such as a parameter or procedure variable) is declared as holding values of a given class. This is called the substitutability principle (from Figure 4-7. Generalization notation Order date: Date confirm() MailOrder confirm() dateFilled: Date BoxOfficeOrder confirm() hold: Boolean generalization superclass (parent) subclass (child) abstract operation 52 Part 2 • UML Concepts Barbara Liskov). The rule is that an instance of a descendant may be used wherever the ancestor is declared. For example, if a variable is declared to hold loans, then a mortgage object is a legal value. Generalization enables polymorphic operations—that is, operations whose implementation (method) is determined by the class of object they are applied to rather than being explicitly stated by the caller. This works because a parent class may have many possible children, each of which implements its own variation of an operation, which is defined across the entire set of classes. For example, computing interest would work differently for a mortgage and an automobile loan, but each of them is a variation on computing interest on the parent Loan class. A variable is declared to hold the parent class, and then an object of any child class can be used, any of which has its own particular operations. This is particularly useful because new classes can be added later, without the need to modify existing polymorphic calls. For example, a new kind of loan could be added later, and existing code that uses the compute interest operation would still work. A polymorphic operation can be declared without an implementation in a parent class with the intent that an implementation must be supplied by each descendant class. Such an incomplete operation is abstract (shown by italicizing its name). The other purpose of generalization is to permit the incremental description of an element by sharing the descriptions of its ancestors. This is called inheritance. Inheritance is the mechanism by which a description of the objects of a class is assembled out of declaration fragments from the class and its ancestors. Inheritance permits shared parts of the description to be declared once and shared by many classes, rather than be repeated in each class that uses it. This sharing reduces the size of a model. More importantly, it reduces the number of changes that must be made on an update to the model and reduces the chance of accidental inconsistency. Inheritance works in a similar way for other kinds of elements, such as states, signals, and use cases. Inheritance Each kind of generalizable element has a set of inheritable properties. For any model element, these include constraints. For classifiers, they also include features (attributes, operations, and signal reception) and participation in associations. A child inherits all the inheritable properties of all its ancestors. Its complete set of properties is the set of inherited properties together with the properties that it declares directly. For a classifier, no attribute with the same signature may be declared more than once (directly or inherited). Otherwise, there is a conflict, and the model is ill formed. In other words, an attribute declared in an ancestor may not be redeclared in a descendant. An operation may be declared in more than one classifier, provided the specifications are consistent (same parameters, constraints, and mean- Chapter 4 • Static View 53 ing). Additional declarations are simply redundant. A method may be declared by multiple classes in a hierarchy. A method attached to a descendant supersedes and replaces (overrides) a method with the same signature declared in any ancestor. If two or more distinct copies of a method are nevertheless inherited by a class (via multiple inheritance from different classes), then they conflict and the model is ill formed. (Some programming languages permit one of the methods to be explicitly chosen. We find it simpler and safer just to redefine the method in the child class.) Constraints on an element are the union of the constraints on the element itself and all its ancestors; if any of them is inconsistent, then the model is ill formed. In a concrete class, each inherited or declared operation must have a method defined, either directly or by inheritance from an ancestor. Multiple inheritance If a classifier has more than one parent, it inherits from each one (Figure 4-8). Its features (attributes, operations, and signals) are the union of those of its parents. If the same class appears as an ancestor by more than one path, it nevertheless contributes only one copy of each of its members. If a feature with the same signature is declared by two classes that do not inherit it from a common ancestor (independent declarations), then the declarations conflict and the model is ill formed. UML does not provide a conflict resolution rule for this situation because experience has shown that the designer should explicitly resolve it. Some Figure 4-8. Multiple inheritance TimeStampedReservation Reservation targetDate: Date TimeStampedTransaction stamp() number: Integer received: Time confirm() This class inherits the attributes and operations of both of its parents. No new features are needed by the child. parent child parent 54 Part 2 • UML Concepts languages, such as Eiffel, permit conflicts to be explicitly resolved by the programmer, which is much safer than implicit conflict resolution rules, which frequently lead to surprises for the developer. Single and multiple classification In the simplest formulation, an object has one direct class. Many object-oriented languages have that restriction. There is no logical necessity that an object have a single class—we typically look at real-world objects from many angles simultaneously. In the more general formulation of UML, an object may have one or more direct classes. The object behaves as if it belonged to an implicit class that was a child of each of the direct classes—effectively, multiple inheritance without the need to actually declare the new class. Static and dynamic classification In the simplest formulation, an object may not change its class after it is created. Again, there is no logical necessity for this restriction. It is primarily intended to make the implementation of object-oriented programming languages easier. In the more general formulation, an object may change its direct class dynamically. In doing so, it may lose or gain attributes or associations. If it loses them, the information in them is lost and cannot be recovered later, even if it changes back to the original class. If it gains attributes or associations, then they must be initialized at the time of the change, in a similar manner to the initialization of a new object. When multiple classification is combined with dynamic classification, an object can gain and lose classes during its life. The dynamic classes are sometimes called roles or types. One common modeling pattern is to require that each object have a single static inherent class (one that cannot change during the life of the object) plus zero or more role classes that may be added or removed over the lifetime of the object. The inherent class describes its fundamental properties, and the role classes describe properties that are transient. Although many programming languages do not support multiple dynamic classification in the class declaration hierarchy, it is nevertheless a valuable modeling concept that can be mapped into associations. Realization The realization relationship connects a model element, such as a class, to another model element, such as an interface, that supplies its behavioral specification but not its structure or implementation. The client must support (by inheritance or by direct declaration) at least all the operations that the supplier has. Although realization is meant to be used with specification elements, such as interfaces, it can also be used with a concrete implementation element to indicate that its specifica- Chapter 4 • Static View 55 tion (but not its implementation) must be supported. This might be used to show the relationship of an optimized version of a class to a simpler but inefficient version, for example. Both generalization and realization relate a more general description to more detailed versions of it. Generalization relates two elements at the same semantic level (at the same level of abstraction, for example), usually within the same model; realization relates two elements at different semantic levels (an analysis class and a design class, for example, or an interface and a class), often found in different models. There may be two or more entire class hierarchies at different stages of development whose elements are related by realization. The two hierarchies need not have the same form because the realizing classes may have implementation dependencies that are not relevant to the specifying classes. Realization is displayed as a dashed arrow with a closed hollow arrowhead (Figure 4-9). It is similar to the generalization symbol with a dashed line, to indicate that it is similar to a kind of inheritance. Figure 4-9. Realization relationship Figure 4-10. Interface and realization icons «interface» ChoiceBlock PopUpMenu RadioButtonArray setDefault (choice: Choice) getChoice (): Choice Choice 1..∗ choice Button String setDefault (choice: Button) getChoice(): Button 1..∗ choice choice 1..∗ setDefault (choice: Button) getChoice(): Button realization relationship specifier implementation PrintServer SubmitJob CheckStatus SetPrintProperties realization interface class interface name 56 Part 2 • UML Concepts There is a special collapsed notation to show interfaces (without their contents) and the classes or components that realize them. The interface is shown as a small circle attached to the classifier rectangle by a solid line (Figure 4-10). Dependencies A dependency indicates a semantic relationship between two or more model elements. It relates the model elements themselves and does not require a set of instances for its meaning. It indicates a situation in which a change to the supplier element may require a change to or indicate a change in meaning of the client element in the dependency. The association and generalization relationships are dependencies by this defi- nition, but they have specific semantics with important consequences. Therefore, they have their own names and detailed semantics. We normally use the word dependency for all the other relationships that don’t fit the sharper categories. Table 4-3 lists the kinds of dependency found in the UML base model. A trace is a conceptual connection among elements in different models, often models at different stages of development. It lacks detailed semantics. It is typically used to trace system requirements across models and to keep track of changes made to models that may affect other models. A refinement is a relationship between two versions of a concept at different stages of development or at different levels of abstraction. The two concepts are not meant to coexist in the final detailed model. One of them is usually a less finished version of the other. In principle, there is a mapping from the less finished concept to the more finished concept. This does not mean that translation is automatic. Usually, the more detailed concept contains design decisions that have been made by the designer, decisions that might be made in many ways. In principle, changes to one model could be validated against the other, with deviations flagged. In practice, tools cannot do all this today, although some simpler mappings can be enforced. Therefore a refinement is mostly a reminder to the modeler that multiple models are related in a predictable way. A derivation dependency indicates that one element can be computed from another element (but the derived element may be explicitly included in the system to avoid a costly recomputation). Derivation, realization, refinement, and trace are abstraction dependencies—they relate two versions of the same underlying thing. A usage dependency is a statement that the behavior or implementation of one element affects the behavior or implementation of another element. Frequently, this comes from implementation concerns, such as compiler requirements that the definition of one class is needed to compile another class. Most usage dependencies can be derived from the code and do not need to be explicitly declared, unless they are part of a top-down design style that constrains the organization of the system (for example, by using predefined components and libraries). The specific Chapter 4 • Static View 57 Table 4-3: Kinds of Dependencies Dependency Function Keyword access Permission for a package to access the contents of another package access binding Assignment of values to the parameters of a template to generate a new model element bind call Statement that a method of one class calls an operation of another class call derivation Statement that one instance can be computed from another instance derive friend Permission for an element to access the contents of another element regardless of visibility friend import Permission for a package to access the contents of another package and add aliases of their names to the importer’s namespace import instantiation Statement that a method of one class creates instances of another class instantiate parameter Relationship between an operation and its parameters parameter realization Mapping between a specification and an implementation of it realize refinement Statement that a mapping exists between elements at two different semantic levels refine send Relationship between the sender of a signal and the receiver of the signal send trace Statement that some connection exists between elements in different models, but less precise than a mapping trace usage Statement that one element requires the presence of another element for its correct functioning (includes call, instantiation, parameter, send, but open to other kinds) use 58 Part 2 • UML Concepts kind of usage dependency can be specified, but this is often omitted because the purpose of the relationship is to highlight the dependency. The exact details can often be obtained from the implementation code. Stereotypes of usage include call and instantiation. The call dependency indicates that a method on one class calls an operation on another class; instantiation indicates that a method on one class creates an instance of another class. Several varieties of usage dependency grant permission for elements to access other elements. The access dependency permits one package to see the contents of another package. The import dependency goes further and adds the names of the target package contents to the namespace of the importing package. The friend dependency is an access dependency that permits the client to see even the private contents of the supplier. A binding is the assignment of values to the parameters of a template. It is a highly structured relationship with precise semantics obtained by substituting the arguments for the parameters in a copy of the template. Usage and binding dependencies involve strong semantics among elements at the same semantic level. They must connect elements in the same level of model (both analysis or both design, and at the same level of abstraction). Trace and re- finement dependencies are vaguer and can connect elements from different models or levels of abstraction. The instance of relationship (a metarelationship, not strictly a dependency) indicates that one element (such as an object) is an instance of another element (such as a class). A dependency is drawn as a dashed arrow from the client to the supplier, with a stereotype keyword to distinguish its kind, as shown in Figure 4-11. Constraint UML supplies a set of concepts and relationships for modeling systems as graphs of modeling elements. Some things, however, are better expressed linguistically— that is, using the power of a textual language. A constraint is a Boolean expression represented as a string to be interpreted in a designated language. Natural language, set theoretic notation, constraint languages, or various programming lanFigure 4-11. Dependencies BoxOffice SchedulingEngine «use» dependency keyword for client supplier dependency type Chapter 4 • Static View 59 guages may be used to express constraints. The UML includes the definition of a constraint language, called OCL, that is convenient for expressing UML constraints and is expected to be widely supported. See the entry for OCL and the book [Warmer-99] for more information on OCL. Constraints can be used to state various nonlocal relationships, such as restrictions on paths of associations. In particular, constraints can be used to state existence properties (there exists an X such that condition C is true) and universal properties (for all y in Y, condition D must be true). Some standard constraints are predefined as UML standard elements, including associations in an exclusive-or relationship and various constraints on the relationships of subclasses in generalization. See Chapter 14, Standard Elements, for more information. A constraint is shown as a text expression in braces. It may be written in a formal language or natural language. The text string may be placed in a note or attached to a dependency arrow. Figure 4-12 shows some constraints. Instances An instance is a run-time entity with identity, that is, something that can be distinguished from other run-time entities. It has a value at any moment in time. Over time the value can change in response to operations on it. One purpose of a model is to describe the possible states of a system and their behavior. A model is a statement of potentiality, of the possible collections of objects that might exist and the possible behavior history that the objects might undergo. The static view defines and constrains the possible configurations of values Figure 4-12. Constraints Member-of Chair-of {subset} Person Committee Person Company boss {Person.employer = Person.boss.employer} worker employer employee 0..1 * * * * * 0..1 1 Represents an incorporated entity. constraint on single class constraint as note constraint on path constraint between associations note 60 Part 2 • UML Concepts that an executing system may assume. The dynamic view defines the ways in which an executing system may pass from one configuration to another. Together, the static view and the various dynamic views based on it define the structure and behavior of a system. A particular static configuration of a system at one instant is called a snapshot. A snapshot comprises objects and other instances, values, and links. An object is an instance of a class. Each object is a direct instance of the class that completely describes it and an indirect instance of the ancestors of that class. (If multiple classification is allowed, then an object may be the direct instance of more than one class.) Similarly, each link is an instance of an association, and each value is an instance of a data type. An object has one data value for each attribute in its class. The value of each attribute must be consistent with the data type of the attribute. If the attribute has optional or multiple multiplicity, then the attribute may hold zero or multiple values. A link comprises a tuple of values, each of which is a reference to an object of a given class (or one of its descendants). Objects and links must obey any constraints on the classes or associations of which they are instances (including both explicit constraints and built-in constraints, such as multiplicity). The state of a system is a valid system instance if every instance in it is an instance of some element in a well-formed system model and if all the constraints imposed by the model are satisfied by the instances. The static view defines the set of objects, values, and links that can exist in a single snapshot. In principle, any combination of objects and links that is consistent with a static view is a possible configuration of the model. This does not mean that every possible snapshot can or will occur. Some snapshots may be legal statically but may not be dynamically reachable under the dynamic views in the system. The behavioral parts of UML describe the valid sequences of snapshots that may occur as a result of both external and internal behavioral effects. The dynamic views define how the system moves from one snapshot to another. Object diagram A diagram of a snapshot is an image of a system at a point in time. Because it contains images of objects, it is called an object diagram. It can be useful as an example of the system, for example, to illustrate complicated data structures or to show behavior through a sequence of snapshots over time (Figure 4-13). Remember that all snapshots are examples of systems, not definitions of systems. The definition of system structure and behavior is found in the definitional views, and constructing the definitional views is the goal of modeling and design. The static view describes the possible instances that can occur. Actual instances do not usually appear directly in models, except as examples. Chapter 4 • Static View 61 Figure 4-13. Object diagram triangle: Polygon point1: Point x = 0.0 y = 1.0 point2: Point x = 3.0 y = 1.0 point3: Point x = 3.0 y = 5.0 object PartOf PartOf PartOf link attribute
Relationships among classifiers are association, generalization, flow, and various kinds of dependency, including realization and usage
The association relationship
describes semantic connections among individual objects of given classes. Associations provide the connections with which objects of different classes can interact.
The generalization relationship relates general descriptions of parent classifiers (superclasses) to more specialized child classifiers (subclasses). Generalization facilitates the description of classifiers out of incremental declaration pieces, each of which adds to the description inherited from its ancestors.
The inheritance mechanism constructs complete descriptions of classifiers from incremental descriptions using generalization relationships. Generalization and inheritance permit different classifiers to share the attributes, operations, and relationships that they have in common, without repetition.
The realization relationship relates a specification to an implementation. An interface is a specification of behavior without implementation; a class includes implementation structure. One or more classes may realize an interface, and each class implements the operations found in the interface.
The flow relationship relates two versions of an object at successive times. It represents a transformation of the value, state, or location of an object. The flow relationship may connect classifier roles in an interaction.
Varieties of flow are become (two versions of the same object) and copy (a new object created from an existing object).
The dependency relationship relates classes whose behavior or implementation affects other classes. There are several kinds of dependency in addition to realization, including trace (a loose connection among elements in different models), re- finement (a mapping between two levels of meaning), usage (a requirement for the presence of another element within a single model), and binding (the assignment of values to template parameters). Usage dependency is frequently used to represent implementation relationships, such as code-level relationships.
Dependency is particularly useful when summarized on model organization units, such as packages, on which it shows the architectural structure of a system. Compilation constraints can be shown by dependencies, for example.
Associations
An association describes discrete connections among objects or other instances in a system. An association relates an ordered list (tuple) of two or more classifiers, with repetitions permitted.
The most common kind of association is a binary association between a pair of classifiers. An instance of an association is a link. A link comprises a tuple (an ordered list) of objects, each drawn from its corresponding class. A binary link comprises a pair of objects.
Associations carry information about relationships among objects in a system. As a system executes, links among objects are created and destroyed.
Associations are the “glue” that ties a system together. Without associations, there are nothing but isolated classes that don’t work together.
A single object may be associated with itself if the same class appears more than once in an association. If the same class appears twice in an association, the two instances do not have to be the same object, and usually they are not.
Each connection of an association to a class is called an association end. Most information about an association is attached to one of its ends. Association ends can have names (rolenames) and visibility.
The most important property they have is multiplicity—how many instances of one class can be related to one instance of the other class.
The notation for a binary association is a line or path connecting the participating classes. The association name is placed along the line with the rolename and multiplicity at each end, as shown in Figure 4-2. An association can also have attributes of its own, in which case it is both an association and a class—an association class (see Figure 4-3).
If an association attribute is unique within a set of related objects, then it is a qualifier (see Figure 4-4). A qualifier is a value that selects a unique object from the set of related objects across an association. Lookup tables and arrays may be modeled as quali- fied associations. Qualifiers are important for modeling names and identification codes. Qualifiers also model indexes in a design model.
A navigable association at the design stage represents state information available to a class, but it can be mapped into programming-language code in various ways. The implementation can be a pointer, a container class embedded in a class, or even a completely separate table object. Other kinds of design properties include visibility and changeability of links. Figure 4-5 shows some design properties of associations.
Aggregation and composition.
An aggregation is an association that represents a part-whole relationship. It is shown by a hollow-diamond adornment on the end of the path attached to the aggregate class. A composition is a stronger form of association in which the composite has sole responsibility for managing its parts— such as their allocation and deallocation. It is shown by a filled-diamond adornment on the composite end. There is a separate association between each class representing a part and the class representing the whole, but for convenience the paths attached to the whole may be joined together so that the entire set of associations is drawn as a tree. Figure 4-6 shows an aggregate and a composite. Links. An instance of an association is a link. A link is an ordered list of object references, each of which must be an instance of the corresponding class in the Figure 4-5. Design properties of association Person Address address 1 TransactionEntry history ∗ {ordered, addOnly} 1 navigability direction ordering property changeability constraint 50 Part 2 • UML Concepts association or an instance of a descendant of the class. The links in a system constitute part of the system state. Links do not exist independently of objects; they take their identity from the objects they relate (in database terms, the list of objects is the key for the link). Conceptually, an association is distinct from the classes that it relates. In practice, associations are often implemented using pointers in the participating classes, but they can be implemented as container objects separate from the classes they connect. Bidirectionality. The different ends of an association are distinguishable, even if two of them involve the same class. This simply means that different objects of the same class can be related. Because the ends are distinguishable, an association is not symmetric (except in special cases); the ends cannot be interchanged. This is only common sense in ordinary discourse; the subject and the object of a verb are not interchangeable. An association is sometimes said to be bidirectional. This means that the logical relationships work both ways. This statement is frequently misunderstood, even by some methodologists. It does not mean that each class “knows” the other class, or that, in an implementation, it is possible to access each class from the other. It simply means that any logical relationship has an inverse, whether or not the inverse is easy to compute. To assert the ability to traverse an association in one direction but not the other as a design decision, associations can be marked with navigability. Why is the basic model relational, rather than the pointer model prevalent in programming languages? The reason is that a model attempts to capture the intent behind an implementation. If a relationship between two classes is modeled as a pair of pointers, the pointers are nevertheless related. The association approach acknowledges that relationships are meaningful in both directions, regardless of how they are implemented. It is simple to convert an association into a pair of pointers for implementation, but very difficult to recognize that two pointers are inverses of each other unless this fact is part of the model. Figure 4-6. Aggregation and composition Order CustomerInfo LineItem composite parts 1 ∗ 1 Subscription Performance ∗ ∗ 1 parts aggregate Chapter 4 • Static View 51 Generalization The generalization relationship is a taxonomic relationship between a more general description and a more specific description that builds on it and extends it. The more specific description is fully consistent with the more general one (it has all its properties, members, and relationships) and may contain additional information. For example, a mortgage is a more specific kind of loan. A mortgage keeps the basic characteristics of a loan but adds additional characteristics, such as a house as security for the loan. The more general description is called the parent; an element in the transitive closure is an ancestor. The more specific description is called the child; an element in the transitive closure is a descendant. In the example, Loan is the parent class and Mortgage is the child class. Generalization is used for classifiers (classes, interfaces, data types, use cases, actors, signals, and so on), packages, state machines, and other elements. For classes, the term superclass and subclass are used for parent and child. A generalization is drawn as an arrow from the child to the parent, with a large hollow triangle on the end connected to the parent (Figure 4-7). Several generalization relationships can be drawn as a tree with one arrowhead branching into several lines to the children. Purpose of generalization. Generalization has two purposes. The first is to define the conditions under which an instance of one class (or other element) can be used when a variable (such as a parameter or procedure variable) is declared as holding values of a given class. This is called the substitutability principle (from Figure 4-7. Generalization notation Order date: Date confirm() MailOrder confirm() dateFilled: Date BoxOfficeOrder confirm() hold: Boolean generalization superclass (parent) subclass (child) abstract operation 52 Part 2 • UML Concepts Barbara Liskov). The rule is that an instance of a descendant may be used wherever the ancestor is declared. For example, if a variable is declared to hold loans, then a mortgage object is a legal value. Generalization enables polymorphic operations—that is, operations whose implementation (method) is determined by the class of object they are applied to rather than being explicitly stated by the caller. This works because a parent class may have many possible children, each of which implements its own variation of an operation, which is defined across the entire set of classes. For example, computing interest would work differently for a mortgage and an automobile loan, but each of them is a variation on computing interest on the parent Loan class. A variable is declared to hold the parent class, and then an object of any child class can be used, any of which has its own particular operations. This is particularly useful because new classes can be added later, without the need to modify existing polymorphic calls. For example, a new kind of loan could be added later, and existing code that uses the compute interest operation would still work. A polymorphic operation can be declared without an implementation in a parent class with the intent that an implementation must be supplied by each descendant class. Such an incomplete operation is abstract (shown by italicizing its name). The other purpose of generalization is to permit the incremental description of an element by sharing the descriptions of its ancestors. This is called inheritance. Inheritance is the mechanism by which a description of the objects of a class is assembled out of declaration fragments from the class and its ancestors. Inheritance permits shared parts of the description to be declared once and shared by many classes, rather than be repeated in each class that uses it. This sharing reduces the size of a model. More importantly, it reduces the number of changes that must be made on an update to the model and reduces the chance of accidental inconsistency. Inheritance works in a similar way for other kinds of elements, such as states, signals, and use cases. Inheritance Each kind of generalizable element has a set of inheritable properties. For any model element, these include constraints. For classifiers, they also include features (attributes, operations, and signal reception) and participation in associations. A child inherits all the inheritable properties of all its ancestors. Its complete set of properties is the set of inherited properties together with the properties that it declares directly. For a classifier, no attribute with the same signature may be declared more than once (directly or inherited). Otherwise, there is a conflict, and the model is ill formed. In other words, an attribute declared in an ancestor may not be redeclared in a descendant. An operation may be declared in more than one classifier, provided the specifications are consistent (same parameters, constraints, and mean- Chapter 4 • Static View 53 ing). Additional declarations are simply redundant. A method may be declared by multiple classes in a hierarchy. A method attached to a descendant supersedes and replaces (overrides) a method with the same signature declared in any ancestor. If two or more distinct copies of a method are nevertheless inherited by a class (via multiple inheritance from different classes), then they conflict and the model is ill formed. (Some programming languages permit one of the methods to be explicitly chosen. We find it simpler and safer just to redefine the method in the child class.) Constraints on an element are the union of the constraints on the element itself and all its ancestors; if any of them is inconsistent, then the model is ill formed. In a concrete class, each inherited or declared operation must have a method defined, either directly or by inheritance from an ancestor. Multiple inheritance If a classifier has more than one parent, it inherits from each one (Figure 4-8). Its features (attributes, operations, and signals) are the union of those of its parents. If the same class appears as an ancestor by more than one path, it nevertheless contributes only one copy of each of its members. If a feature with the same signature is declared by two classes that do not inherit it from a common ancestor (independent declarations), then the declarations conflict and the model is ill formed. UML does not provide a conflict resolution rule for this situation because experience has shown that the designer should explicitly resolve it. Some Figure 4-8. Multiple inheritance TimeStampedReservation Reservation targetDate: Date TimeStampedTransaction stamp() number: Integer received: Time confirm() This class inherits the attributes and operations of both of its parents. No new features are needed by the child. parent child parent 54 Part 2 • UML Concepts languages, such as Eiffel, permit conflicts to be explicitly resolved by the programmer, which is much safer than implicit conflict resolution rules, which frequently lead to surprises for the developer. Single and multiple classification In the simplest formulation, an object has one direct class. Many object-oriented languages have that restriction. There is no logical necessity that an object have a single class—we typically look at real-world objects from many angles simultaneously. In the more general formulation of UML, an object may have one or more direct classes. The object behaves as if it belonged to an implicit class that was a child of each of the direct classes—effectively, multiple inheritance without the need to actually declare the new class. Static and dynamic classification In the simplest formulation, an object may not change its class after it is created. Again, there is no logical necessity for this restriction. It is primarily intended to make the implementation of object-oriented programming languages easier. In the more general formulation, an object may change its direct class dynamically. In doing so, it may lose or gain attributes or associations. If it loses them, the information in them is lost and cannot be recovered later, even if it changes back to the original class. If it gains attributes or associations, then they must be initialized at the time of the change, in a similar manner to the initialization of a new object. When multiple classification is combined with dynamic classification, an object can gain and lose classes during its life. The dynamic classes are sometimes called roles or types. One common modeling pattern is to require that each object have a single static inherent class (one that cannot change during the life of the object) plus zero or more role classes that may be added or removed over the lifetime of the object. The inherent class describes its fundamental properties, and the role classes describe properties that are transient. Although many programming languages do not support multiple dynamic classification in the class declaration hierarchy, it is nevertheless a valuable modeling concept that can be mapped into associations. Realization The realization relationship connects a model element, such as a class, to another model element, such as an interface, that supplies its behavioral specification but not its structure or implementation. The client must support (by inheritance or by direct declaration) at least all the operations that the supplier has. Although realization is meant to be used with specification elements, such as interfaces, it can also be used with a concrete implementation element to indicate that its specifica- Chapter 4 • Static View 55 tion (but not its implementation) must be supported. This might be used to show the relationship of an optimized version of a class to a simpler but inefficient version, for example. Both generalization and realization relate a more general description to more detailed versions of it. Generalization relates two elements at the same semantic level (at the same level of abstraction, for example), usually within the same model; realization relates two elements at different semantic levels (an analysis class and a design class, for example, or an interface and a class), often found in different models. There may be two or more entire class hierarchies at different stages of development whose elements are related by realization. The two hierarchies need not have the same form because the realizing classes may have implementation dependencies that are not relevant to the specifying classes. Realization is displayed as a dashed arrow with a closed hollow arrowhead (Figure 4-9). It is similar to the generalization symbol with a dashed line, to indicate that it is similar to a kind of inheritance. Figure 4-9. Realization relationship Figure 4-10. Interface and realization icons «interface» ChoiceBlock PopUpMenu RadioButtonArray setDefault (choice: Choice) getChoice (): Choice Choice 1..∗ choice Button String setDefault (choice: Button) getChoice(): Button 1..∗ choice choice 1..∗ setDefault (choice: Button) getChoice(): Button realization relationship specifier implementation PrintServer SubmitJob CheckStatus SetPrintProperties realization interface class interface name 56 Part 2 • UML Concepts There is a special collapsed notation to show interfaces (without their contents) and the classes or components that realize them. The interface is shown as a small circle attached to the classifier rectangle by a solid line (Figure 4-10). Dependencies A dependency indicates a semantic relationship between two or more model elements. It relates the model elements themselves and does not require a set of instances for its meaning. It indicates a situation in which a change to the supplier element may require a change to or indicate a change in meaning of the client element in the dependency. The association and generalization relationships are dependencies by this defi- nition, but they have specific semantics with important consequences. Therefore, they have their own names and detailed semantics. We normally use the word dependency for all the other relationships that don’t fit the sharper categories. Table 4-3 lists the kinds of dependency found in the UML base model. A trace is a conceptual connection among elements in different models, often models at different stages of development. It lacks detailed semantics. It is typically used to trace system requirements across models and to keep track of changes made to models that may affect other models. A refinement is a relationship between two versions of a concept at different stages of development or at different levels of abstraction. The two concepts are not meant to coexist in the final detailed model. One of them is usually a less finished version of the other. In principle, there is a mapping from the less finished concept to the more finished concept. This does not mean that translation is automatic. Usually, the more detailed concept contains design decisions that have been made by the designer, decisions that might be made in many ways. In principle, changes to one model could be validated against the other, with deviations flagged. In practice, tools cannot do all this today, although some simpler mappings can be enforced. Therefore a refinement is mostly a reminder to the modeler that multiple models are related in a predictable way. A derivation dependency indicates that one element can be computed from another element (but the derived element may be explicitly included in the system to avoid a costly recomputation). Derivation, realization, refinement, and trace are abstraction dependencies—they relate two versions of the same underlying thing. A usage dependency is a statement that the behavior or implementation of one element affects the behavior or implementation of another element. Frequently, this comes from implementation concerns, such as compiler requirements that the definition of one class is needed to compile another class. Most usage dependencies can be derived from the code and do not need to be explicitly declared, unless they are part of a top-down design style that constrains the organization of the system (for example, by using predefined components and libraries). The specific Chapter 4 • Static View 57 Table 4-3: Kinds of Dependencies Dependency Function Keyword access Permission for a package to access the contents of another package access binding Assignment of values to the parameters of a template to generate a new model element bind call Statement that a method of one class calls an operation of another class call derivation Statement that one instance can be computed from another instance derive friend Permission for an element to access the contents of another element regardless of visibility friend import Permission for a package to access the contents of another package and add aliases of their names to the importer’s namespace import instantiation Statement that a method of one class creates instances of another class instantiate parameter Relationship between an operation and its parameters parameter realization Mapping between a specification and an implementation of it realize refinement Statement that a mapping exists between elements at two different semantic levels refine send Relationship between the sender of a signal and the receiver of the signal send trace Statement that some connection exists between elements in different models, but less precise than a mapping trace usage Statement that one element requires the presence of another element for its correct functioning (includes call, instantiation, parameter, send, but open to other kinds) use 58 Part 2 • UML Concepts kind of usage dependency can be specified, but this is often omitted because the purpose of the relationship is to highlight the dependency. The exact details can often be obtained from the implementation code. Stereotypes of usage include call and instantiation. The call dependency indicates that a method on one class calls an operation on another class; instantiation indicates that a method on one class creates an instance of another class. Several varieties of usage dependency grant permission for elements to access other elements. The access dependency permits one package to see the contents of another package. The import dependency goes further and adds the names of the target package contents to the namespace of the importing package. The friend dependency is an access dependency that permits the client to see even the private contents of the supplier. A binding is the assignment of values to the parameters of a template. It is a highly structured relationship with precise semantics obtained by substituting the arguments for the parameters in a copy of the template. Usage and binding dependencies involve strong semantics among elements at the same semantic level. They must connect elements in the same level of model (both analysis or both design, and at the same level of abstraction). Trace and re- finement dependencies are vaguer and can connect elements from different models or levels of abstraction. The instance of relationship (a metarelationship, not strictly a dependency) indicates that one element (such as an object) is an instance of another element (such as a class). A dependency is drawn as a dashed arrow from the client to the supplier, with a stereotype keyword to distinguish its kind, as shown in Figure 4-11. Constraint UML supplies a set of concepts and relationships for modeling systems as graphs of modeling elements. Some things, however, are better expressed linguistically— that is, using the power of a textual language. A constraint is a Boolean expression represented as a string to be interpreted in a designated language. Natural language, set theoretic notation, constraint languages, or various programming lanFigure 4-11. Dependencies BoxOffice SchedulingEngine «use» dependency keyword for client supplier dependency type Chapter 4 • Static View 59 guages may be used to express constraints. The UML includes the definition of a constraint language, called OCL, that is convenient for expressing UML constraints and is expected to be widely supported. See the entry for OCL and the book [Warmer-99] for more information on OCL. Constraints can be used to state various nonlocal relationships, such as restrictions on paths of associations. In particular, constraints can be used to state existence properties (there exists an X such that condition C is true) and universal properties (for all y in Y, condition D must be true). Some standard constraints are predefined as UML standard elements, including associations in an exclusive-or relationship and various constraints on the relationships of subclasses in generalization. See Chapter 14, Standard Elements, for more information. A constraint is shown as a text expression in braces. It may be written in a formal language or natural language. The text string may be placed in a note or attached to a dependency arrow. Figure 4-12 shows some constraints. Instances An instance is a run-time entity with identity, that is, something that can be distinguished from other run-time entities. It has a value at any moment in time. Over time the value can change in response to operations on it. One purpose of a model is to describe the possible states of a system and their behavior. A model is a statement of potentiality, of the possible collections of objects that might exist and the possible behavior history that the objects might undergo. The static view defines and constrains the possible configurations of values Figure 4-12. Constraints Member-of Chair-of {subset} Person Committee Person Company boss {Person.employer = Person.boss.employer} worker employer employee 0..1 * * * * * 0..1 1 Represents an incorporated entity. constraint on single class constraint as note constraint on path constraint between associations note 60 Part 2 • UML Concepts that an executing system may assume. The dynamic view defines the ways in which an executing system may pass from one configuration to another. Together, the static view and the various dynamic views based on it define the structure and behavior of a system. A particular static configuration of a system at one instant is called a snapshot. A snapshot comprises objects and other instances, values, and links. An object is an instance of a class. Each object is a direct instance of the class that completely describes it and an indirect instance of the ancestors of that class. (If multiple classification is allowed, then an object may be the direct instance of more than one class.) Similarly, each link is an instance of an association, and each value is an instance of a data type. An object has one data value for each attribute in its class. The value of each attribute must be consistent with the data type of the attribute. If the attribute has optional or multiple multiplicity, then the attribute may hold zero or multiple values. A link comprises a tuple of values, each of which is a reference to an object of a given class (or one of its descendants). Objects and links must obey any constraints on the classes or associations of which they are instances (including both explicit constraints and built-in constraints, such as multiplicity). The state of a system is a valid system instance if every instance in it is an instance of some element in a well-formed system model and if all the constraints imposed by the model are satisfied by the instances. The static view defines the set of objects, values, and links that can exist in a single snapshot. In principle, any combination of objects and links that is consistent with a static view is a possible configuration of the model. This does not mean that every possible snapshot can or will occur. Some snapshots may be legal statically but may not be dynamically reachable under the dynamic views in the system. The behavioral parts of UML describe the valid sequences of snapshots that may occur as a result of both external and internal behavioral effects. The dynamic views define how the system moves from one snapshot to another. Object diagram A diagram of a snapshot is an image of a system at a point in time. Because it contains images of objects, it is called an object diagram. It can be useful as an example of the system, for example, to illustrate complicated data structures or to show behavior through a sequence of snapshots over time (Figure 4-13). Remember that all snapshots are examples of systems, not definitions of systems. The definition of system structure and behavior is found in the definitional views, and constructing the definitional views is the goal of modeling and design. The static view describes the possible instances that can occur. Actual instances do not usually appear directly in models, except as examples. Chapter 4 • Static View 61 Figure 4-13. Object diagram triangle: Polygon point1: Point x = 0.0 y = 1.0 point2: Point x = 3.0 y = 1.0 point3: Point x = 3.0 y = 5.0 object PartOf PartOf PartOf link attribute
No comments:
Post a Comment