JETZT ONLINE BESTELLEN
Add to Cart
UML 2.0 in a Nutshell

First Edition Juli 2005
ISBN 978-0-596-00795-9
234 Seiten
EUR32.00

Weitere Informationen zu diesem Buch

Inhaltsverzeichnis | Kolophon |


Inhaltsverzeichnis

	
Chapter 1: Fundamentals of UML
Inhaltsvorschau
On the surface, the Unified Modeling Language (UML) is a visual language for capturing software designs and patterns. Dig a little deeper, though, and you'll find that UML can be applied to quite a few different areas and can capture and communicate everything from company organization to business processes to distributed enterprise software. It is intended to be a common way of capturing and expressing relationships, behaviors, and high-level ideas in a notation that's easy to learn and efficient to write. UML is visual; just about everything in it has a graphical representation. Throughout this book we'll discuss the meaning behind the various UML elements as well as their representations.
If you're new to UML, you should be sure to read this chapter all the way through to get acquainted with the basic terminology used throughout the book. If you are a developer, class diagrams tend to be the simplest diagrams to start with because they map closely to code. Pick a program or domain you know well, and try to capture the entities involved using classes. Once you're convinced you've modeled the relationships between your entities correctly, pick a piece of functionality and try to model that using a sequence diagram and your classes.
If you're more of a process person (business or otherwise), you may be more comfortable starting with an activity diagram. Chapter 9 shows examples of modeling business processes with different groups (Human Resources, IT, etc.) and progresses to modeling parallel processes over different geographic regions.
UML has become the de facto standard for modeling software applications and is growing in popularity in modeling other domains. Its roots go back to three distinct methods: the Booch Method by Grady Booch, the Object Modeling Technique coauthored by James Rumbaugh, and Objectory by Ivar Jacobson. Known as the Three Amigos, Booch, Rumbaugh, and Jacobson kicked off what became the first version of UML, in 1994. In 1997, UML was accepted by the Object Management Group (OMG) and released as UML v1.1.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Getting Started
Inhaltsvorschau
If you're new to UML, you should be sure to read this chapter all the way through to get acquainted with the basic terminology used throughout the book. If you are a developer, class diagrams tend to be the simplest diagrams to start with because they map closely to code. Pick a program or domain you know well, and try to capture the entities involved using classes. Once you're convinced you've modeled the relationships between your entities correctly, pick a piece of functionality and try to model that using a sequence diagram and your classes.
If you're more of a process person (business or otherwise), you may be more comfortable starting with an activity diagram. Chapter 9 shows examples of modeling business processes with different groups (Human Resources, IT, etc.) and progresses to modeling parallel processes over different geographic regions.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Background
Inhaltsvorschau
UML has become the de facto standard for modeling software applications and is growing in popularity in modeling other domains. Its roots go back to three distinct methods: the Booch Method by Grady Booch, the Object Modeling Technique coauthored by James Rumbaugh, and Objectory by Ivar Jacobson. Known as the Three Amigos, Booch, Rumbaugh, and Jacobson kicked off what became the first version of UML, in 1994. In 1997, UML was accepted by the Object Management Group (OMG) and released as UML v1.1.
Since then, UML has gone through several revisions and refinements leading up to the current 2.0 release. Each revision has tried to address problems and shortcomings identified in the previous versions, leading to an interesting expansion and contraction of the language. UML 2.0 is by far the largest UML specification in terms of page count (the superstructure alone is over 600 pages), but it represents the cleanest, most compact version of UML yet.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
UML Basics
Inhaltsvorschau
First and foremost, it is important to understand that UML is a language. This means it has both syntax and semantics. When you model a concept in UML, there are rules regarding how the elements can be put together and what it means when they are organized in a certain way. UML is intended not only to be a pictorial representation of a concept, but also to tell you something about its context. How does widget 1 relate to widget 2? When a customer orders something from you, how should the transaction be handled? How does the system support fault tolerance and security?
You can apply UML in any number of ways, but common uses include:
  • Designing software
  • Communicating software or business processes
  • Capturing details about a system for requirements or analysis
  • Documenting an existing system, process, or organization
UML has been applied to countless domains, including:
  • Banking and investment sectors
  • Health care
  • Defense
  • Distributed computing
  • Embedded systems
  • Retail sales and supply
The basic building block of UML is a diagram. There are several types, some with very specific purposes (timing diagrams) and some with more generic uses (class diagrams). The following sections touch on some of the major ways UML has been employed. The diagrams mentioned in each section are by no means confined to that section. If a particular diagram helps you convey your message you should use it; this is one of the basic tenants of UML modeling.
Because UML grew out of the software development domain, it's not surprising that's where it still finds its greatest use. When applied to software, UML attempts to bridge the gap between the original idea for a piece of software and its implementation. UML provides a way to capture and discuss requirements at the requirements level (use case diagrams), sometimes a novel concept for developers. There are diagrams to capture what parts of the software realize certain requirements (collaboration diagrams). There are diagrams to capture exactly
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
UML Specifications
Inhaltsvorschau
Physically, UML is a set of specifications from the OMG. UML 2.0 is distributed as four specifications: the Diagram Interchange Specification , the UML Infrastructure, the UML Superstructure, and the Object Constraint Language (OCL). All of these specifications are available from the OMG web site, http://www.omg.org.
The Diagram Interchange Specification was written to provide a way to share UML models between different modeling tools. Previous versions of UML defined an XML schema for capturing what elements were used in a UML diagram, but did not capture any information about how a diagram was laid out. To address this, the Diagram Interchange Specification was developed along with a mapping from a new XML schema to a Scalable Vector Graphics (SVG) representation. Typically the Diagram Interchange Specification is used only by tool vendors, though the OMG makes an effort to include "whiteboard tools."
The UML Infrastructure defines the fundamental, low-level, core, bottom-most concepts in UML; the infrastructure is a metamodel that is used to produce the rest of UML. The infrastructure isn't typically used by an end user, but it provides the foundation for the UML Superstructure.
The UML Superstructure is the formal definition of the elements of UML, and it weighs in at over 600 pages. This is the authority on all that is UML, at least as far as the OMG is concerned. The superstructure documentation is typically used by tool vendors and those writing books on UML, though some effort has been made to make it human readable.
The OCL specification defines a simple language for writing constraints and expressions for elements in a model. The OCL is often brought into play when you specify UML for a particular domain and need to restrict the allowable values for a parameter or object. Appendix B is an overview of the OCL.
It is important to realize that while the specification is the definitive source of the formal definition of UML, it is by no means the be-all and end-all of UML. UML is designed to be extended and interpreted depending on the domain, user, and specific application. There is enough wiggle room in the specification to fit a data center through it... this is intentional. For example, there are typically two or more ways to represent a UML concept depending on what looks best in your diagram or what part of a concept you wish to emphasize. You may choose to represent a particular element using an in-house notation; this is perfectly acceptable as far as UML is concerned. However, you must be careful when using nonstandard notation because part of the reason for using UML in the first place is to have a common representation when collaborating with other users.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Putting UML to Work
Inhaltsvorschau
A UML model provides a view of a system—often just one of many views needed to actually build or document the complete system. Users new to UML can fall into the trap of trying to model everything about their system with a single diagram and end up missing critical information. Or, at the other extreme, they may try to incorporate every possible UML diagram into their model, thereby overcomplicating things and creating a maintenance nightmare.
Becoming proficient with UML means understanding what each diagram has to offer and knowing when to apply it. There will be many times when a concept could be expressed using any number of diagrams; pick the one(s) that will mean the most to your users.
Each chapter of this book describes a type of diagram and gives examples of its use. There are times when you may need to have more than one diagram to capture all the relevant details for a single part of your system. For example, you may need a statechart diagram to show how an embedded controller processes input from a user as well as a timing diagram to show how the controller interacts with the rest of the system as a result of that input.
You should also consider your audience when creating models. A test engineer may not care about the low-level implementation (sequence diagram) of a component, only the external interfaces it offers (component diagram). Be sure to consider who will be using each diagram you produce and make it meaningful to that person.
In addition to a variety of diagram types, UML is designed to be extended. You can informally extend UML by adding constraints, stereotypes, tagged values, and notes to your models, or you can use the formal UML extension and define a full UML profile. A UML profile is a collection of stereotypes and constraints on elements that map the otherwise generic UML to a specific problem domain or implementation. For example, there are profiles for CORBA, Enterprise Application Integration (EAI), fault tolerance, database modeling, and testing. See Chapter 11 for more information on UML 2.0 Profiles.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Modeling
Inhaltsvorschau
It should go without saying that the focus of UML is modeling. However, what that means, exactly, can be an open-ended question. Modeling is a means to capture ideas, relationships, decisions, and requirements in a well-defined notation that can be applied to many different domains. Modeling not only means different things to different people, but also it can use different pieces of UML depending on what you are trying to convey.
In general a UML model is made up of one or more diagrams. A diagram graphically represents things, and the relationships between these things. These things can be representations of real-world objects, pure software constructs, or a description of the behavior of some other object. It is common for an individual thing to show up on multiple diagrams; each diagram represents a particular interest, or view, of the thing being modeled.
UML 2.0 divides diagrams into two categories: structural diagrams and behavioral diagrams. Structural diagrams are used to capture the physical organization of the things in your system—i.e., how one object relates to another. There are several structural diagrams in UML 2.0:
Class diagrams
Class diagrams use classes and interfaces to capture details about the entities that make up your system and the static relationships between them. Class diagrams are one of the most commonly used UML diagrams, and they vary in detail from fully fleshed-out and able to generate source code to quick sketches on whiteboards and napkins. Class diagrams are discussed in Chapter 2.
Component diagrams
Component diagrams show the organization and dependencies involved in the implementation of a system. They can group smaller elements, such as classes, into larger, deployable pieces. How much detail you use in component diagrams varies depending on what you are trying to show. Some people simply show the final, deployable version of a system, and others show what functionality is provided by a particular component and how it realizes its functionality internally. Component diagrams are discussed in Chapter 5.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
UML Rules of Thumb
Inhaltsvorschau
While UML provides a common language for capturing functionality and design information, it is deliberately open-ended to allow for the flexibility needed to model different domains. There are several rules of thumb to keep in mind when using UML:
Nearly everything in UML is optional
UML provides a language to capture information that varies greatly depending on the domain of the problem. In doing that, there are often parts of UML that either don't apply to your particular problem or may not lend anything to the particular view you are trying to convey. It is important to realize that you don't need to use every part of UML in every model you create. Possibly even more importantly, you don't need to use every allowable symbol for a diagram type in every diagram you create. Show only what helps clarify the message you are trying to convey, and leave off what you don't need. At times there is more than one way to convey the same information; use what is familiar to your audience.
UML models are rarely complete
As a consequence of everything being optional, it is common for a UML model to be missing some details about a system. The trick is to not miss key details that could impact your system design. Knowing what is a key detail versus extraneous information comes with experience; however, using an iterative process and revisiting your model helps to flesh out what needs to be there. As UML moves closer to tool automation with practices like MDA and Software Factories, the models often become more and more detailed and therefore complete. The difference is the tool support that helps vary the level of abstraction depending on your needs.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 2: Class Diagrams
Inhaltsvorschau
Class diagrams are one of the most fundamental diagram types in UML. They are used to capture the static relationships of your software; in other words, how things are put together.
When writing software you are constantly making design decisions: what classes hold references to other classes, which class "owns" some other class, and so on. Class diagrams provide a way to capture this "physical" structure of a system.
A class represents a group of things that have common state and behavior. You can think of a class as a blueprint for an object in an object-oriented system. In UML speak, a class is a kind of classifier. For example, Volkswagen, Toyota, and Ford are all cars, so you can represent them using a class named Car. Each specific type of car is an instance of that class, or an object. A class may represent a tangible and concrete concept, such as an invoice; it may be abstract, such as a document or a vehicle (as opposed to an invoice, or a motorcycle greater than 1000 cc), or it may represent an intangible concept such as a high-risk investment strategy.
You represent a class with a rectangular box divided into compartments. A compartment is simply an area in the rectangle to write information. The first compartment holds the name of the class, the second holds attributes (see "Attributes"), and the third is used for operations (see "Operations"). You can hide any compartment of the class if that increases the readability of your diagram. When reading a diagram, you can make no assumptions about a missing compartment; it doesn't mean it is empty. You may add compartments to a class to show additional information, such as exceptions or events, though this is outside of the typical notation.
UML suggests that the class name:
  • Start with a capital letter
  • Be centered in the top compartment
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Classes
Inhaltsvorschau
A class represents a group of things that have common state and behavior. You can think of a class as a blueprint for an object in an object-oriented system. In UML speak, a class is a kind of classifier. For example, Volkswagen, Toyota, and Ford are all cars, so you can represent them using a class named Car. Each specific type of car is an instance of that class, or an object. A class may represent a tangible and concrete concept, such as an invoice; it may be abstract, such as a document or a vehicle (as opposed to an invoice, or a motorcycle greater than 1000 cc), or it may represent an intangible concept such as a high-risk investment strategy.
You represent a class with a rectangular box divided into compartments. A compartment is simply an area in the rectangle to write information. The first compartment holds the name of the class, the second holds attributes (see "Attributes"), and the third is used for operations (see "Operations"). You can hide any compartment of the class if that increases the readability of your diagram. When reading a diagram, you can make no assumptions about a missing compartment; it doesn't mean it is empty. You may add compartments to a class to show additional information, such as exceptions or events, though this is outside of the typical notation.
UML suggests that the class name:
  • Start with a capital letter
  • Be centered in the top compartment
  • Be written in a boldface font
  • Be written in italics if the class is abstract (see "Abstract Classes")
Figure 2-1 shows a simple class.
Figure 2-1: Simple class representation
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Attributes
Inhaltsvorschau
Details of a class (the color of a car, the number of sides in a shape, etc.) are represented as attributes . Attributes can be simple primitive types (integers, floating-point numbers, etc.) or relationships to other, complex objects (see "Relationships").
An attribute can be shown using two different notations: inlined or relationships between classes. In addition, notation is available to show such things as multiplicity, uniqueness, and ordering. This section introduces both notations, and then describes the details of the attribute specification.
You can list a class's attributes right in rectangle notation; these are typically called inlined attributes . There is no semantic difference between inlined attributes and attributes by relationship; it's simply a matter of how much detail you want to present (or, in the case of primitives like integers, how much detail you can present).
To represent an attribute within the body of a class, place the attribute in the second compartment of the class. UML refers to inlined attributes as attribute notation . Inlined attributes use the following notation:

               visibility

               

               

               

               

                / name : type 

               multiplicity = default

  {property strings and constraints}

 

visibility ::= {+|-|#|~}

 

multiplicity ::= [lower..upper]

Figure 2-3 lists several attributes, demonstrating various aspects of attribute notation.
Figure 2-3: Example attributes
The syntax elements are:
visibility
Indicates the visibility of the attribute. Use the following symbols: +, -, #, or ~ for public, private, protected
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Operations
Inhaltsvorschau
Operations are features of classes that specify how to invoke a particular behavior. For example, a class may offer an operation to draw a rectangle on the screen or count the number of items selected in a list. UML makes a clear distinction between the specification of how to invoke a behavior (an operation) and the actual implementation of that behavior (a method). See "Methods" for more information.
You place operations in a separate compartment with the following syntax:

            visibility name ( parameters ) : return-type {properties}

         
where parameters are written as:

            direction parameter_name : type [ multiplicity ]

  = default_value { properties }

         
Figure 2-13 shows several example operations on a class.
Figure 2-13: Example operations on a class
The syntax elements are:
visibility
Indicates the visibility of the operation. Use the following symbols: +, -, #, or ~ for public, private, protected, or package, respectively (see "Visibility" in Chapter 3).
name
Is a short phrase naming the operation. Operations are usually verb phrases representing actions the classifier should perform on behalf of the caller. The UML specification recommends that the first letter of an operation be lowercase, with all of the following words starting with a capital letter and running together. See Figure 2-13 for an example.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Methods
Inhaltsvorschau
A method is an implementation of an operation. Each class typically provides an implementation for its operations or inherits them from its superclass (see "Generalization"). If a class doesn't provide an implementation for an operation, and one isn't provided by its superclass, the operation is considered abstract . See "Abstract Classes" for more information. Because methods are implementations of operations, there is no notation for a method; simply show an operation on a class.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Abstract Classes
Inhaltsvorschau
An abstract class is typically a class that provides an operation signature, but no implementation; however, you can have an abstract class that has no operations at all. An abstract class is useful for identifying common functionality across several types of objects. For example, you can have an abstract class named Movable. A Movable object has a current position and the ability to move somewhere else using an operation named move(). There can be several specializations of this abstract class—a Car, a Grasshopper, and a Person, each of which provides a different implementation of move(). Because the base class Movable doesn't have an implementation for move(), the class is said to be abstract.
You show a class is abstract by writing its name in italics. Show each abstract operation in italics as well. Figure 2-20 is an example of the abstract class Movable.
Figure 2-20: Abstract class
An abstract class can't be instantiated; it must be subclassed and then a subclass which does provide the operation implementation can be instantiated. See "Relationships" for more information on subclasses.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Relationships
Inhaltsvorschau
Classes in isolation would not provide much insight into how a system is designed. UML provides several ways of representing relationships between classes. Each of UML relationship represents a different type of connection between classes and has subtleties that aren't fully captured in the UML specification. When modeling in the real world, be sure that your intended viewers understand what you are conveying with your various relationships. We say this both as a warning to the modeler and as a slight disclaimer that the following explanations are our interpretation of the UML specification. For example, the debate over when to use aggregation versus composition is ongoing. To help determine which relationship is most appropriate, we offer a short phrase for each type that may help make the distinction. Again, the important thing is to be consistent within your model.
The weakest relationship between classes is a dependency relationship. Dependency between classes means that one class uses, or has knowledge of, another class. It is typically a transient relationship, meaning a dependent class briefly interacts with the target class but typically doesn't retain a relationship with it for any real length of time.
Dependencies are typically read as "...uses a...". For example, if you have a class named Window that sends out a class named WindowClosingEvent when it is about to be closed, you would say "Window uses a WindowClosingEvent."
You show a dependency between classes using a dashed line with an arrow pointing from the dependent class to the class that is used. Figure 2-21 shows a dependency between a class named Window and a class named WindowClosingEvent.
Figure 2-21: Window's dependency on WindowClosingEvent
You can likely assume from Figure 2-21 that Window doesn't retain a relationship with a WindowClosingEvent
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Interfaces
Inhaltsvorschau
An interface is a classifier that has declarations of properties and methods but no implementations. You can use interfaces to group common elements between classifiers and provide a contract a classifier that provides an implementation of an interface must obey. For example, you can create an interface named Sortable that has one operation named comesBefore(...). Any class that realizes the Sortable interface must provide an implementation of comesBefore(...).
Some modern languages, such as C++, don't support the concept of interfaces; UML interfaces are typically represented as pure abstract classes. Other languages, such as Java, do support interfaces but don't allow them to have properties. The moral is that you should be aware of how your model is going to be implemented when modeling your system.
There are two representations for an interface; which one you should use depends on what you're trying to show. The first representation is the standard UML classifier notation with the stereotype «interface». Figure 2-31 shows the Sortable interface.
Figure 2-31: The Sortable interface
The second representation of an interface is the ball-and-socket notation. This representation shows less detail for the interface but is more convenient for showing relationships to classes. The interface is simply shown as a ball with the name of the interface written below it. Classes dependent on this interface are shown attached to a socket matching the interface. Figure 2-32 shows the Sortable interface using the ball-and-socket notation.
Figure 2-32: Examples of providing and requiring interfaces
Because an interface specifies the contract only for a set of features, you can't instantiate an interface directly. Instead, a class is said to
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Templates
Inhaltsvorschau
Just as interfaces allow you to provide specifications for objects your class will interact with, UML allows you to provide abstractions for the type of class your class may interact with. For example, you can write a List class that can hold any type of object (in C++ this would probably be a void*, in Java and C# it would probably be an Object). However, while you wanted your List class to be able to support any type of object, you want all of the objects in a given list to be of the same type. UML allows you to create and specify these kinds of abstractions using templates .
You can indicate that a class is a templated (also called parameterized ) class by drawing a dashed rectangle in the upper-right corner of the class. For each element you would like to template, you need to specify a name to act as a placeholder for the actual type. Write the placeholder name in the rectangle. Figure 2-34 shows an example of a List class that can support any type.
Figure 2-34: A templated List class
This example uses ElementType as the name of the templated type for clarity. In practice, this is often abbreviated to just T.
You can have multiple templated types within a single class; just separate the type names with a comma (,). If you need to restrict the types the user may substitute, show that with a colon (:) followed by the type name. Figure 2-35 shows a more complicated version of the List class that requires a Sorter along with the type of object to store in the list.
Figure 2-35: A templated class with type restrictions
Specifying restrictions on a type that may be used is functionally similar to specifying an interface for a templated member, except that the user may be able to further restrict an instance of your class by specifying a subclass of your type.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Variations on Class Diagrams
Inhaltsvorschau
Because class diagrams model structures well, they can be used to capture well-defined, hierarchical information. Class diagrams have been used to capture XML and database schemas with some degree of success. In the interest of full disclosure, people who deal with XML and database schemas extensively have reservations about using class diagrams to capture the information, specifically because class diagrams are so generic. Each domain has its own notation that may be better suited to capturing complex relationships or domain-specific information. However, UML has the benefit of being a common language that is understood by those outside the XML and database domains.
The structural design of an XML document can be captured in an XML schema. XML schemas are to XML documents as classes are to objects; XML documents are instances of a schema. Therefore, it's not a giant leap to realize that class diagrams can be used to model XML schemas. XML schemas are described using the XML Structure Definition Language (XSDL). XSDL is a text language (as opposed to the graphical nature of UML) and can be verbose; mapping XSDL to UML can make it much easier to digest a schema document.
The fundamental elements of XSDL are XML elements, which are connected in sequences, choices, and complex structures. Each element may have extra information attached to it using (conveniently enough) attributes. Modelers typically represent XML elements as classes and XSDL attributes as UML attributes. Each element is linked to the next using composition arrows. Multiplicity specifications on the relationships show how many times one element appears within another. Example 2-1 is a sample XML document that describes a piece of equipment.
Example 2-1. A sample XML document

<?xml version="1.0" encoding="UTF-8"?>

<equipmentlist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:noNamespaceSchemaLocation="equipment.xsd">

    <equipment equipmentid="H-1">

        <shortname>

            <langstring lang="en">Hammer</langstring>

        </shortname>

        <technicalcontact>

            <contact>

                <name>Ron</name>

                <telephone>555-1212</telephone>

            </contact>

        </technicalcontact>

        <trainingcontact>

            <contact>

                <name>Joe</name>

                <email>joe@home.com</email>

            </contact>

        </trainingcontact>

    </equipment>

</equipmentlist>

Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 3: Package Diagrams
Inhaltsvorschau
Packages provide a way to group related UML elements and scope their names. For example, you can put all elements having to do with 3D rendering into a package named 3DGraphics. Package diagrams provide a great way to visualize dependencies between parts of your system and are often used to look for problems or determine compilation order.
Nearly all UML elements can be grouped into packages, including packages themselves. Each package has a name that scopes each element in the package. For example, if you had a class named Timer in a package named Utilities, the fully qualified name for the class is Utilities::Timer. Elements in the same package can refer to each other without qualifying their names.
You show a package using a rectangle with a tab attached to the top left. Figure 3-1 shows the Utilities package.
Figure 3-1: A simple package
You can show the elements contained within a package in two different ways. First, you can show the elements contained within the package by drawing them inside the large rectangle. If you use this representation , write the name of the package in the tab. Figure 3-2 shows the contents of the Utilities package inside of the package. To refer to the Timer class from outside of the Utilities package, you say Utilities::Timer.
Figure 3-2: Several classes contained inside the Utilities package
The second representation uses a solid line pointing from the package to each contained element. You place a circle with a plus sign in it at the end nearest the package to indicate containment. If you use this representation, you should show the name of the package in the large rectangle rather than in the tab. This notation allows you to show more detail of the packaged elements. Figure 3-3 shows the same
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Representation
Inhaltsvorschau
You show a package using a rectangle with a tab attached to the top left. Figure 3-1 shows the Utilities package.
Figure 3-1: A simple package
You can show the elements contained within a package in two different ways. First, you can show the elements contained within the package by drawing them inside the large rectangle. If you use this representation , write the name of the package in the tab. Figure 3-2 shows the contents of the Utilities package inside of the package. To refer to the Timer class from outside of the Utilities package, you say Utilities::Timer.
Figure 3-2: Several classes contained inside the Utilities package
The second representation uses a solid line pointing from the package to each contained element. You place a circle with a plus sign in it at the end nearest the package to indicate containment. If you use this representation, you should show the name of the package in the large rectangle rather than in the tab. This notation allows you to show more detail of the packaged elements. Figure 3-3 shows the same Utilities package but with the classes broken out.
Figure 3-3: Elements owned by a package, shown outside of the package
You don't need to show all the elements contained within a package; if no elements are shown, no assumptions can be made about what the package contains.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Visibility
Inhaltsvorschau
A package may specify visibility information for owned and imported elements, however elements may have only one of two levels of visibility: public or private. Public visibility means the element may be used outside the package (scoped by the package name). Private visibility means the element may be used only by other elements of the same package. Private visibility is useful for marking utility classes that help implement a subsystem or component you don't want to expose to the rest of the system.
You show public visibility by placing a plus sign before the element name. You show private visibility using a minus sign. Figure 3-4 shows the Utility package with some private helper classes.
Figure 3-4: The Utilities package with public and private members
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Importing and Accessing Packages
Inhaltsvorschau
When accessing elements in one package from a different package, you must qualify the name of the element you are accessing. For example, if Car is a class in the Transportation package and you are trying to access it from a package named RoutePlanning, you need to qualify Car as Transportation::Car.
To simplify accessing elements in a different package, UML allows a package to import another package. Elements of the imported package are available without qualification in the importing package. So, if the RoutePlanning package imported the Transportation package, you can refer to Car without any qualifications from within the RoutePlanning package.
To show a package import, you draw a dashed line with an open arrow from the importing package to the imported package. Label this line with the «import» keyword. Figure 3-5 shows the RoutePlanning package importing the Transportation package.
Figure 3-5: RoutePlanning importing the Transportation package
By default, imported elements are given public visibility in the importing package. UML allows you to specify that imported elements should be given private visibility, meaning they can't be used by anyone outside the importing package (including any packages that may import that package). To specify that imported elements should have private visibility, you use the «access» keyword rather than the «import» keyword. Figure 3-6 shows the RoutePlanning package importing the Transportation package and accessing the Algorithms package. If a package imports the RoutePlanning package, both packages can use public elements from Transportation, but they can't use anything in Algorithms.
Figure 3-6: RoutePlanning importing the Transportation package but accessing only the Algorithms package
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Merging Packages
Inhaltsvorschau
UML supports a somewhat complex concept of merging packages. Merging packages differs from importing packages in that merge, by definition, creates relationships between classes of the same name. The motivation behind package merging comes directly from the evolution of UML from 1.x to 2.0. UML 2.0 defines the base concept of elements and allows specific diagram types to extend a base concept without needing to provide a new name for it. For example, UML extends several core Behavioral State Machine concepts into Protocol State Machine concepts while retaining their original name.
When a package merges another package, any class of the same type and name automatically extends (or has a generalization relationship to) the original class. For example, UML can define the concept of the include relationship at a generic level and then specialize it for use cases inclusion and retain the name include. This type of extension has simplified the internals of the UML model but rarely makes an appearance in real-world development.
You show package merging using a dashed line with an open arrow from the merging package to the merged package. Label this line with the keyword «merge». Figure 3-7 shows an example of merging two packages.
Figure 3-7: ProtocolStateMachines merging the elements from BehavioralStateMachines so it can add to the contained classes
The rules for package merge are:
  • Private members of a package aren't merged with anything.
  • Classes in the package performing the merge that have the same name and type as classes in the merged package(s) get a generalization relationship to the merged class(es). Note that this can result in multiple inheritance, but UML allows this.
  • You can still reference any of the original classes by explicitly scoping the class using the original package name.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Variations on Package Diagrams
Inhaltsvorschau
This section presents two applications of class package diagrams and one application of use case packages. Although layering and simplification always motivate packaging, the term "simplification" means different things to different people. Simplification can mean:
  • Easier to build and test
  • Better tracking and project transparency
  • Working at a stable overview without the noise of low-level churn
  • Less conflict between distributed teams
  • Easy refactoring and extension
Simplification likely means more apparent complexity to some constituency. Unless your packaging balances these diverse needs, you are likely to receive complaints of unnecessary complexity, no matter how noble your motives are.
Class packages organize a logical system during construction. They provide the terms for management and external stakeholders, as well as structure to contain all classes and code to be built. Class package diagrams are the UML equivalent of block diagrams.
Different parties think of a project according to their different needs. Programmers think in terms of language and tactical design. Architects think in terms of dependencies, risk, technology, building, testing, and OO principles. Project managers think in terms of risk, tracking, resources, need, ownership, required skills, and delivery. Although all issues are important, and good packaging recognizes its responsibility to all needs, architects tend to identify top-level packaging with an eye on the control functions of project management. For example, a project manager might draw a package diagram for a web application such as that shown in Figure 3-8.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 4: Composite Structures
Inhaltsvorschau
As a system becomes more complex, it is often helpful to decompose it in terms of functionality (see Chapter 7). To realize a piece of functionality, different elements of a system often work together and communicate information. UML 2.0 formalizes the concept of complex relationships between elements into the idea of composite structures. Much of the material in this chapter is new to UML 2.0.
A structure is a set of interconnected elements that exist at runtime to collectively provide some piece of functionality. For example, you can use a structure to represent the internal makeup of a classifier such as a subsystem (what objects are related to each other, who is communicating with whom, etc.). UML calls such structures internal structures. UML defines several symbols to capture the relationships and communications between elements in an internal structure.
Connectors represent communication links between instances of classes participating in an internal structure. They can be runtime instances of associations, or they can represent dynamic communication set up at runtime—for example by being values of local variables. You show a connector as a solid line between two instances. Note that while associations between classes represent a link between any instances of those classes, a connector represents a link between only the two instances specified at each end of the connector (see "Collaborations").
You can provide name and type information for a connector using the following format:

               name:classname

            
where:
name
Is the name of the connector. The name can be used later in collaborations to reference this connector.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Composite Structures
Inhaltsvorschau
A structure is a set of interconnected elements that exist at runtime to collectively provide some piece of functionality. For example, you can use a structure to represent the internal makeup of a classifier such as a subsystem (what objects are related to each other, who is communicating with whom, etc.). UML calls such structures internal structures. UML defines several symbols to capture the relationships and communications between elements in an internal structure.
Connectors represent communication links between instances of classes participating in an internal structure. They can be runtime instances of associations, or they can represent dynamic communication set up at runtime—for example by being values of local variables. You show a connector as a solid line between two instances. Note that while associations between classes represent a link between any instances of those classes, a connector represents a link between only the two instances specified at each end of the connector (see "Collaborations").
You can provide name and type information for a connector using the following format:

               name:classname

            
where:
name
Is the name of the connector. The name can be used later in collaborations to reference this connector.
classname
Is the name of an association this connector represents.
Figure 4-1 is an example of a named connector.
Figure 4-1: The link between a Pedal and a Wheel is a connector named "c," which is a Chain
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Collaborations
Inhaltsvorschau
One of the primary purposes for composite structures is to document how a particular piece of functionality is implemented within a system. This organization of elements to realize behavior is called a collaboration . A collaboration is a collection of instances wired together using connectors to show the communication flow.
Because the purpose of collaborations is to describe how a particular piece of functionality works, details outside the scope of the desired functionality are typically left off a diagram. Instead, a collaboration diagram shows the required links between instances and the attributes involved in the collaboration. You may have multiple collaborations involving the same instances but showing different views of each based on the functionality expressed. One effective way of showing different views of a classifier is to use interfaces to collect related functionality. A single class may realize multiple interfaces, but each collaboration can focus on a single interface. See "Interfaces" in Chapter 2 for more information.
Within a collaboration, it is helpful to name the instances involved. You typically name an instance based on its role in the collaboration. For example, if you wish to model the Observer/Observable design pattern, you will likely have an instance in the role of Observer and an instance in the role of Subject.
You show a collaboration using a dashed ellipse with the name of the collaboration written inside. Figure 4-15 shows a collaboration named "Observer/Observable."
Figure 4-15: A simple collaboration
There are two ways to render the details of a collaboration. The first is to add a compartment to the collaboration ellipse and draw the instances involved in the collaboration inside. Links between instances are shown as solid lines. Each instance is named according to its role in the collaboration. Figure 4-16 shows the internal structure of the Observer/Observable collaboration.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Collaboration Occurrences
Inhaltsvorschau
UML 2.0 introduced a new concept to allow you to attach a collaboration to a specific operation or classifier to show how it is realized by other elements. When you associate a collaboration with an operation or classifier, you create a collaboration occurrence . You can think of collaboration occurrences as instances of collaborations. For example, you can use a collaboration occurrence to document how various classes make up a subsystem, what is responsible for persistence, what is really a façade to another subsystem, etc. The advantage of using a collaboration occurrence to document the implementation of functionality is that you can assign role names to internal elements of the classifier. There may be multiple occurrences of a particular collaboration within a classifier, each with different internal elements fulfilling the roles of the collaboration.
You show a collaboration occurrence using the same dashed ellipse used to show a collaboration, except that you list the name of the occurrence followed by a colon, and then the name of the collaboration type. For each role used in the original collaboration, you draw a dashed line from the collaboration occurrence to the element fulfilling the role. You label the dashed line with the name of the role. For example, a collaboration occurrence of our Observer/Observable collaboration is shown in Figure 4-18.
Figure 4-18: Two collaboration occurrences of the Observer/Observable collaboration
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 5: Component Diagrams
Inhaltsvorschau
When modeling large software systems it is common to break the software into manageable subsystems. UML provides the component classifier for exactly this purpose. A component is a replaceable, executable piece of a larger system whose implementation details are hidden. The functionality provided by a component is specified by a set of provided interfaces that the component realizes (see "Black-Box View"). In addition to providing interfaces, a component may require interfaces in order to function. These are called required interfaces.
The functionality of a component's provided interfaces is implemented with one or more internal classifiers. These are typically classes but can be other components (see "White-Box View"). Components should be designed to be reused, with dependencies on external interfaces, strong encapsulation, and high cohesion.
In UML 2.0, you represent a component with the classifier rectangle stereotyped as «component». Like other classifiers, if the details of the component aren't shown, you place the name of the component in the center of the rectangle. Optionally, you may show the component icon (a rectangle with two smaller rectangles on the left side) in the upper-right corner. Figure 5-1 shows a simple component.
Figure 5-1: A simple component
The representation for a component has changed from previous versions of UML. UML 1.4 recognized a, rectangle with two smaller rectangles:
This notation is still recognized for backward compatibility but is no longer recommended.
Components may need other components to implement their functionality. You can show component dependencies using the dependency relation (a dashed line with an open arrow) between the two components. Figure 5-2 shows the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Components
Inhaltsvorschau
In UML 2.0, you represent a component with the classifier rectangle stereotyped as «component». Like other classifiers, if the details of the component aren't shown, you place the name of the component in the center of the rectangle. Optionally, you may show the component icon (a rectangle with two smaller rectangles on the left side) in the upper-right corner. Figure 5-1 shows a simple component.
Figure 5-1: A simple component
The representation for a component has changed from previous versions of UML. UML 1.4 recognized a, rectangle with two smaller rectangles:
This notation is still recognized for backward compatibility but is no longer recommended.
Components may need other components to implement their functionality. You can show component dependencies using the dependency relation (a dashed line with an open arrow) between the two components. Figure 5-2 shows the AccountManagement component dependent on two other components.
Figure 5-2: Component dependency
Representing component dependencies in this fashion is a relatively high-level view of a system. To further refine the diagram you may want to show inter-component relationships as dependencies on the interfaces provided by other dependent components (see "Black-Box View"; also see "Interfaces" in Chapter 2).
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Component Views
Inhaltsvorschau
UML uses two views of components, a black-box view and a white-box view. The black-box view shows a component from an outside perspective; the white-box view shows how a component realizes the functionality specified by its provided interfaces.
The black-box view of a component shows the interfaces the component provides, the interfaces it requires, and any other detail necessary to explain the guaranteed behavior of the component. It does not specify anything about the internal implementation of the component. This distinction is central to the concept of replaceable components.

Section 5.2.1.1: Assembly connectors

When modeling a black-box view of a component, you represent the provided and required interfaces using assembly connectors . Assembly connectors are illustrated using ball-and-socket icons. To show a required interface, use the socket icon and write the name of the interface near the connector symbol. Figure 5-3 shows a component with two required interfaces.
Figure 5-3: Component with two required interfaces
Show a provided interface with the ball half of an assembly connector, again with the name of the interface near the symbol. Figure 5-4 shows a component with a provided interface.
Figure 5-4: Component with a provided interface
To wire components together, simply connect the matching provided and required interfaces. Component dependencies using assembly connectors provide more details about the actual relationships between components than simple dependency relations. Figure 5-5 shows the same three components from the "Component Dependencies" section, but using assembly connectors.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 6: Deployment Diagrams
Inhaltsvorschau
Deployment diagrams model the mapping of software pieces of a system to the hardware that is going to execute it. Software elements (components, classes, etc.) are typically manifested using artifacts and are mapped to the hardware or software environment that will host them, called nodes. Because many nodes may be associated with the deployment of a system, communication between nodes can be modeled using communication paths.
Artifacts represent physical pieces of information related to the software development process. For example, you can use an artifact to represent a DLL needed by your system, a user's manual, or an executable produced when your software is compiled.
Typically artifacts are used to represent the compiled version of a component (see Chapter 5); however, UML 2.0 allows artifacts to represent any packageable element, which includes just about everything in UML. You show an artifact using the classifier rectangle with a dog-eared paper in the upper right. Figure 6-1 shows a basic artifact.
Figure 6-1: A simple artifact
UML allows artifacts to have properties and operations that manipulate the artifact. These are most commonly used when an artifact represents a set of configurable options. For example, deployment specifications , which represent configuration settings for deployed artifacts, frequently use attributes to represent the allowed settings (see "Deployment Specifications"). Figure 6-2 shows an artifact with attributes.
Figure 6-2: An artifact with attributes
Like nearly all other UML classifiers, artifacts are really types. This means that technically a physical DLL on a node is an instance of an artifact. For example, you can have an artifact named
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Artifacts
Inhaltsvorschau
Artifacts represent physical pieces of information related to the software development process. For example, you can use an artifact to represent a DLL needed by your system, a user's manual, or an executable produced when your software is compiled.
Typically artifacts are used to represent the compiled version of a component (see Chapter 5); however, UML 2.0 allows artifacts to represent any packageable element, which includes just about everything in UML. You show an artifact using the classifier rectangle with a dog-eared paper in the upper right. Figure 6-1 shows a basic artifact.
Figure 6-1: A simple artifact
UML allows artifacts to have properties and operations that manipulate the artifact. These are most commonly used when an artifact represents a set of configurable options. For example, deployment specifications , which represent configuration settings for deployed artifacts, frequently use attributes to represent the allowed settings (see "Deployment Specifications"). Figure 6-2 shows an artifact with attributes.
Figure 6-2: An artifact with attributes
Like nearly all other UML classifiers, artifacts are really types. This means that technically a physical DLL on a node is an instance of an artifact. For example, you can have an artifact named logging.jar that represents your logging framework implementation. However, you may have several web applications installed on a server, each with their own copy of logging.jar. Each physical copy is an instance of the original artifact.
You show an instance of an artifact by underlining the name of the artifact. Figure 6-3 shows an instance of the logging.jar artifact.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Nodes
Inhaltsvorschau
A node is a physical entity that can execute artifacts. Nodes can vary in size from a simple embedded device to a server farm. Nodes are a critical piece of any deployment diagram because they show where a particular piece of code executes and how the various pieces of the system (at the execution level) communicate.
You show a node as a 3D box with the name of the node written inside. However, possibly more than any other classifier in UML, modelers typically use specific icon representations of nodes to help convey the type of hardware represented. Figure 6-5 shows a simple node as a cube, as well as example icon representations.
Figure 6-5: Several nodes using the cube representation, and some example icon representations
Previous versions of UML did not define any specializations of a node. UML 2.0 specializes a node into two different aspects of hosting code: the required software and the required hardware. Therefore, it is less common to see a generic node in UML 2.0 diagrams than it was in UML 1.x. See "Execution Environments" and "Devices" for more information.
An execution environment is a specialized node that represents a software configuration hosting specific types of artifacts. An execution environment is expected to provide specific services to hosted artifacts by means of mutually agreed upon interfaces. For example, a Java 2 Enterprise Edition (J2EE) application expects to run in a software environment called an Application Server . The J2EE specification enumerates several services that should be provided by an Application Server, such as database connectivity, lifecycle contracts, and resource location. You can express that a node is an Application Server (and therefore provides the required services) by defining a stereotype for the node. For example, a typical stereotype for an Application Server is
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Deployment
Inhaltsvorschau
The most important aspect of deployment diagrams is conveying the relationship between artifacts and the node(s) they execute on. When you associate an artifact with a deployment target (anything that can host an artifact, such as a device or execution environment), you deploy that artifact. For example, you may have an artifact named ccvalidator.jar that represents the credit card validation subsystem of an application. When you say ccvalidator.jar executes on the node Appserver1, you have deployed the artifact.
UML provides several ways to show deployment. You may show artifact deployment by simply drawing an artifact in the hosting node's cube. Figure 6-13 shows an artifact named ccvalidator.jar deployed to the device Appserver1.
UML also allows you to show deployment using a dashed line with an open arrow (dependency) pointing from the artifact to the deployment target. You should stereotype this line with the keyword «deploy». Figure 6-14 shows the same deployment relationship as Figure 6-13, but uses the dependency notation.
Finally, you may show deployment by simply listing deployed artifacts in a compartment in the deployment target's classifier. This notation is particularly useful if you have a lot of artifacts deployed to a single node. Figure 6-15 shows an execution environment with several deployed artifacts.
Figure 6-13: An artifact deployed to a device
Figure 6-14: Artifact deployment using a dependency relationship
Figure 6-15: An execution environment with a list of the deployed artifacts
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Variations on Deployment Diagrams
Inhaltsvorschau
Most of the time deployment diagrams are used for their intended purpose: to show how an application is physically deployed. Some modelers prefer to display the bare minimum, just showing how many machines they will need and how they are supposed to talk. Modelers often take liberties with the official notation and will specify minimum requirements for their machines, as in Figure 6-18.
Figure 6-18: A minimal deployment diagram
Obviously Figure 6-18 doesn't provide any information on actual software deployment. Instead of focusing on the node's configuration, you can focus on the software deployment configuration and specify details for executing your software, as shown in Figure 6-19.
Figure 6-19: Detailed application deployment diagram
For the sake of completeness, we should mention that deployment diagrams have been used to show network configurations. Properties and tagged values can be used to show network configuration options rather than machine hardware details. Figure 6-20 shows an example network modeled as a deployment diagram. Be warned, though: deployment diagrams were not designed with network modeling in mind, so a professional network administrator may find the syntax lacking.
Figure 6-20: A sample network topology using a deployment diagram
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 7: Use Case Diagrams
Inhaltsvorschau
Use cases are a way to capture system functionality and requirements in UML. Use case diagrams consist of named pieces of functionality (use cases ), the persons or things invoking the functionality (actors), and possibly the elements responsible for implementing the use cases (subjects ).
Use cases represent distinct pieces of functionality for a system, a component, or even a class. Each use case must have a name that is typically a few words describing the required functionality, such as View Error Log. UML provides two ways to draw a use case. The first is an oval with the name of the use case in the center. Figure 7-1 shows a basic use case.
Figure 7-1: A simple use case
You can divide a use case's oval into compartments to provide more detail about the use case, such as extension points (see "Use Case Extension"), included use cases (see "Use Case Inclusion"), or the modeling of specific constraints. Figure 7-2 shows a use case oval with a compartment listing extension points.
However, the oval representation of use cases doesn't hold up well with detailed compartments. UML recommends you use the classifier notation if you want to provide details about a use case. Show the use case as a rectangle, with the use case oval in the top-right corner. Now, place the name of the use case in the top, in bold. You can then divide the classifier into compartments as needed. Typical
Figure 7-2: Use case with a compartment showing extension points
compartment names are extension points and included use cases . Figure 7-3 shows the same use case as in Figure 7-2, but in classifier notation.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Use Cases
Inhaltsvorschau
Use cases represent distinct pieces of functionality for a system, a component, or even a class. Each use case must have a name that is typically a few words describing the required functionality, such as View Error Log. UML provides two ways to draw a use case. The first is an oval with the name of the use case in the center. Figure 7-1 shows a basic use case.
Figure 7-1: A simple use case
You can divide a use case's oval into compartments to provide more detail about the use case, such as extension points (see "Use Case Extension"), included use cases (see "Use Case Inclusion"), or the modeling of specific constraints. Figure 7-2 shows a use case oval with a compartment listing extension points.
However, the oval representation of use cases doesn't hold up well with detailed compartments. UML recommends you use the classifier notation if you want to provide details about a use case. Show the use case as a rectangle, with the use case oval in the top-right corner. Now, place the name of the use case in the top, in bold. You can then divide the classifier into compartments as needed. Typical
Figure 7-2: Use case with a compartment showing extension points
compartment names are extension points and included use cases . Figure 7-3 shows the same use case as in Figure 7-2, but in classifier notation.
Figure 7-3: Use case in classifier notation
UML makes a clear distinction that the term use case strictly applies to the UML element and its name. Full documentation of a use case is considered an instantiation of the use case. This is a subtle distinction, but it allows you to document a use case whatever way best captures the use case's functionality. You can document a use case in a text document, state machine, interaction diagram, activity diagram, or anything else that conveys the details of the functionality in a meaningful way to your reader.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Actors
Inhaltsvorschau
A use case must be initiated by someone or something outside the scope of the use case. This interested party is called an actor. An actor doesn't need to be a human user; any external system or element outside of the use case may trigger the use case (or be the recipient of use case results) and should be modeled as an actor. For example, it is very common to model the system clock as an actor that triggers a use case at a given time or interval.
An actor can have several different representations in UML. The first is a stick figure with the name of the actor written near the icon (usually right below it). Figure 7-4 shows an actor icon.
Alternatively, an actor can be shown using the classifier notation. You represent the actor with a rectangle, with the keyword actor at the top and the name of the actor in bold immediately below that. Because actors don't typically have compartments, this representation isn't used very often. Figure 7-5 shows an actor in classifier notation.
If it is helpful, you may use custom icons to clearly distinguish different types of actors. For example, you can show an external database system using a database
Figure 7-4: An actor using the stick figure representation
Figure 7-5: An actor using classifier notation
icon while showing the system administrator as a stick figure. Figure 7-6 shows exactly this set of actors.
Figure 7-6: Actor with a custom icon
You typically associate an actor with one or more use cases. A relationship between an actor and a use case indicates the actor initiates the use case, the use case provides the actor with results, or both. You show an association between an actor and a use case as a solid line. Conventionally you read use case diagrams from left to right, with actors initiating use cases on the left and actors that receive use case results on the right. However, depending on the model or level of complexity, it may make sense to group actors differently. Figure 7-7 shows an actor communicating with a use case.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Advanced Use Case Modeling
Inhaltsvorschau
As it does for other classifiers, UML provides mechanisms for reusing and adding on to use cases and actors. You can expand an actor's capabilities or replace entire use cases using generalization . You can factor out common elements of use cases using included use cases, or add on to base use cases using use case extension.
Though not officially mentioned in the specification, actors and use cases can be generalized like many other classifiers. Actor generalization is typically used to pull out common requirements from several different actors to simplify modeling. For example, Figure 7-10 shows several administrators and the use cases they need to invoke. You may have a Database Administrator, a Backup Administrator, and a Deployment Administrator, all with slightly different needs. However, the majority of the needs of the individual actors may overlap. You can factor out a generic System Administrator actor to capture the common functionality, and then specialize to identify the unique needs of each actor.
You represent actor generalization like any other classifier; draw a solid line, with a closed arrow pointing from the specialized actor to the base actor. Figure 7-11 shows the same information as Figure 7-10 but in a much easier-to-read diagram.
Use cases may be generalized as well. Typically use case generalization is used to express some high-level functional need of a system without going into specifics. Specializations of a general use case introduce specific functionality. For example, a generic use case can be Verify Passenger Identity, and specializations of that use case can be Check Passenger Fingerprint and Verify Passenger's RFID Tag. It is important to notice that even with use case generalization, you should still discuss functionality, not implementation. You should not have specializations of a use case for different ways to implement the same functionality, only to represent different functionality.
You represent use case generalization just like you do actor generalization: using a solid line, with a closed arrow pointing from the specialized use case to the base use case. If the general use case represents abstract functionality (meaning it's a functional concept but doesn't actually explain how a user would do something), you show the name of the use case in italics. Figure 7-12 shows the verification use cases and their relationships.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Use Case Scope
Inhaltsvorschau
As mentioned previously, a use case is a distinct piece of functionality, meaning it is of sufficient granularity that the user has accomplished his desired goal. Proper scoping of use cases is an art, but UML sets several requirements to make the job a little easier:
  • A use case must be initiated by an actor.
  • When a use case is considered complete, there are no further inputs or outputs; the desired functionality has been performed, or an error has occurred.
  • After a use case has completed, the system is in a state where the use case can be started again, or the system is in an error state.
One popular rule of thumb is to ask yourself if the user can "go to lunch" after completing the use case, meaning that a reasonably sized goal has been achieved by the initiator. For example, Add item to shopping cart is probably not the larger goal a user intends; Purchase item is likely a better scope. Purchase item can consist of adding an item to a shopping cart but typically has more functionality such as logging on, entering billing and shipping information, and confirming the order.
Above all, use cases are intended to convey desired functionality, so the exact scope of a use case may vary depending on the intended audience and purpose for modeling.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 8: Statechart Diagrams
Inhaltsvorschau
State machine diagrams capture the behavior of a software system. State machines can be used to model the behavior of a class, subsystem, or entire application. They also provide an excellent way of modeling communications that occur with external entities via a protocol or event-based system.
UML has two types of state machines:
Behavioral state machines
Show the behavior of model elements such as objects. A behavioral state machine represents a specific implementation of an element.
Protocol state machines
Show the behavior of a protocol. Protocol state machines show how participants may trigger changes in a protocol's state and the corresponding changes in the system (i.e., the new state of the protocol). Protocol state machines aren't typically tied to a particular implementation, and they show the required protocol behavior.
Behavioral and protocol state machines share common elements; however, protocol state machines are not tied to an implementation and have restrictions on their transitions. Because protocol state machines are a specialization of behavioral state machines , this chapter first discusses behavioral state machines and other topics common to all state machine diagrams; then details of protocol state machines are explained.
State machines represent the behavior of a piece of a system using graph notation. A state machine is shown using the basic rectangle notation, with the name of the state machine shown in the top compartment. The outside rectangle is often omitted on state machine diagrams that show only a single state machine. The metaclass is simply state machine. Figure 8-1 shows a simple state machine modeling a soda machine.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Behavioral State Machines
Inhaltsvorschau
State machines represent the behavior of a piece of a system using graph notation. A state machine is shown using the basic rectangle notation, with the name of the state machine shown in the top compartment. The outside rectangle is often omitted on state machine diagrams that show only a single state machine. The metaclass is simply state machine. Figure 8-1 shows a simple state machine modeling a soda machine.
Figure 8-1: A basic state machine
A state machine is often associated with a classifier in the larger UML model—for example, a class or subsystem. However, UML doesn't define a specific notation to show this relationship. One possible notation is to use a note labeled with the name of the state machine and linked to the classifier. Figure 8-2 shows an example that uses a note to link a state machine to a classifier.
Figure 8-2: Example of linking a state machine to a classifier
You can model the behavior of the classifier using states, pseudostates, activities, and transitions. If a state machine is used to model the behavior of an operation (see "Operations" in Chapter 2), the state machine must have parameters that match the operation's parameters. These can be used in any transition or state as needed.
Transitions between states occur when events are dispatched (see "Dispatch"). As the state machine executes, activities are run based upon the transition, entry into a state, and so on (see "Activities").
Each state machine has a set of connection points that define the external interface to the state machine. These connection points must be either Entry or Exit pseudostates.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
States
Inhaltsvorschau
States model a specific moment in the behavior of a classifier. This moment in time is defined by some condition being true in the classifier.
States model a situation in the behavior of a classifier when an invariant condition holds true. Put more simply, a state is a "condition of being" for the state machine and, by association, the classifier that's being modeled. For example, a coffee machine could be "Grinding Beans," "Brewing," "Warming Coffee," "Dispensing," etc. A state can represent a static situation, such as "Waiting for Username" or a dynamic situation where the state is actively processing data, such as "Encrypting Message."
A state is shown as a rectangle with rounded corners. The name of the state is written inside the rectangle. Figure 8-3 shows a simple state.
Figure 8-3: A simple state
A state name may be placed outside of the rectangle in a tab notation when showing composite or submachine states (see "Composite States" and "Submachine States"). You should either use the tab notation or place the name inside the state; don't do both. Figure 8-4 shows a state using a tab for the state name.
Figure 8-4: A state with its name in a tab
Within the rectangle a state can be divided into compartments as needed. UML defines the following compartments:
Name
Shows the name of the state. This should not be used if the name is placed in a tab.
Internal activities
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
State Machine Extension
Inhaltsvorschau
Like many other concepts in UML, state machines may be specialized as needed. A specialized state machine is an extension of a general state machine. You can specialize a state machine by adding regions, states, pseudostates, or transitions. In addition to adding features to state machines you can redefine states, regions, and transitions.
When drawing a specialized state machine, draw the inherited states with dashed or gray-toned lines. You may also place the keyword extended in curly braces after the name of the state machine. Figure 8-16 shows a specialized soda dispensing state machine. The Dispensing Drink state is extended to introduce a new substate, Out of selection. The states Releasing drink and Refunding change retain their other transitions, and a new transition, Time expired, is added to transition to the new substate if the IR sensor isn't triggered (see Figure 8-6 for the original composite state).
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Protocol State Machines
Inhaltsvorschau
Protocol state machines capture the behavior of a protocol, such as HTTP or a challenge-response speakeasy door. They aren't tied to a particular implementation of a protocol; rather, they specify the state changes and events associated with a protocol-based communication.
Unlike in behavioral state machines, states in protocol state machines represent stable situations where the classifier isn't processing any operation and the user knows its configuration.
Figure 8-16: State machine extension
Protocol state machines differ from behavioral state machines in the following ways:
  • entry, exit, and do activities can't be used.
  • States can have invariants. Place invariants in square brackets under the state name.
  • The keyword protocol is placed in curly braces after the state machine name to indicate the state machine is a protocol state machine.
  • Transitions in protocol state machines have a precondition (in place of the guard in normal transitions), the trigger, and a post condition. The notation for a protocol transition is as follows:

    [precondition] event / [postcondition]
  • Each transition is associated with zero or one operation on the owning classifier. The transition guarantees that the precondition will be true before the operation is invoked, and that the post condition will be true before entering the target state.
  • The effect activity is never specified for a protocol transition.
Figure 8-17 shows a simplified version of the Simple Mail Transport Protocol (SMTP) protocol. Because protocol state machines don't not allow activities, there is little detail about what the SMTP server actually does when receiving a command from the client. By design, the protocol state machine tells you only what state the protocol implementation will be in, not what it does to get there or how it keeps itself occupied. See "Variations on Statechart Diagrams" for an example of modeling a protocol in more detail.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Pseudostates
Inhaltsvorschau
Pseudostates are special types of states that represent specific behavior during transitions between regular states. Combined with basic transitions, pseudostates can represent complex state changes within a state machine.
Figure 8-17: A simplified SMTP protocol state machine
Table 8-1 shows the types of pseudostates and their symbols. Refer to Figure 8-1 for an example showing how these symbols are used.
Table 8-1: Types of pseudostates
Pseudostate name
Symbol
Description
Initial pseudostate
The starting point of a state machine. The transition from the initial pseudostate to the first full state may be labeled with the event that instantiates the object the state machine is modeling.
Choice
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Event Processing
Inhaltsvorschau
Information within a state machine is conveyed via events. Events can be triggered by things outside of the state machine or as part of an activity executing within a state. An event can have parameters and attributes you can use when processing the event.
As events are triggered, they are added to an event pool. Once added to the event pool, events are sent out for processing by the state machine or are dispatched. The order of event dispatch and processing isn't specified by UML. This allows state machines to impose their own prioritization schemes on events if desired.
When dispatching events, a new event is dispatched and processed only after the previous event has been fully processed. This doesn't mean that all do activities (see "Activities") are complete, just that the state machine is in a well-defined condition, with entry and exit activities completed. This is called run-to-completion by the UML specification.
After an event is dispatched, if no transitions are enabled and the event isn't deferred (see "Deferred Events"), the event is discarded, and the next event can be processed.
If an event does trigger one or more transitions, such as in the case of orthogonal states (see "Composite States"), the order in which the transitions are fired isn't specified by UML. Once all transitions have been fired, the event is considered complete.
If a synchronous activity is triggered by a transition, the event processing isn't complete until the invoked object has finished its run-to-completion step.
When dispatching events, UML allows for transitions to conflict. However, only one out of a set of conflicting transitions is allowed to execute. If an event triggers two different transitions from the same state, the state machine must select only one transition to execute. The following rules determine which transition executes:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Variations on Statechart Diagrams
Inhaltsvorschau
In addition to modeling behavior and protocols, statecharts have been used to capture real-time system behavior. As they do with many applications of UML diagrams, real-time system modelers frequently use tagged values and constraints to customize the syntax for their organization; however, almost all real-time diagrams include some notation to indicate time. A common notation is to use the keyword after to indicate a maximum allowable time for a transition to occur. Figure 8-19 shows a satellite uplink acquisition statechart that requires a ground station to respond to satellite commands within a fixed amount of time to prevent the acquisition sequence from failing and starting over.
Since real-time systems are frequently involved in well-defined protocols, the line between real-time state machines and protocol state machines can blur. There is no real notational difference; it is a matter of what the modeler is trying to convey. Real-time state machines often model the internal states of a system, something
Figure 8-19: A sample real-time statechart diagram
deliberately avoided by protocol state machines. If the modeler doesn't capture the internal states of a system, or if the implementation is simple enough that there are no additional internal states, the state machine can wind up being a model of the protocol. Figure 8-19 is closer to a protocol state machine than a detailed implementation model; each state in the figure can be represented by one or more smaller, internal states in a real implementation. However, according to the strict definition of protocol state machines, entry activities can't be used, so Figure 8-19 isn't tagged with the {protocol} tag.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 9: Activity Diagrams
Inhaltsvorschau
Activity modeling focuses on the execution and flow of the behavior of a system, rather than how it is assembled. Possibly more than any other UML diagram, activity diagrams apply to much more than just software modeling. They are applicable to just about any type of behavioral modeling; for example, business processes, software processes, or workflows. Activity diagrams capture activities that are made up of smaller actions .
When used for software modeling, activities typically represent a behavior invoked as a result of a method call. When used for business modeling, activities may be triggered by external events, such as an order being placed, or internal events, such as a timer to trigger the payroll process on Friday afternoons. Activity diagrams have undergone significant changes with UML 2.0; they have been promoted to first-class elements and no longer borrow elements from state diagrams.
An activity is a behavior that is factored into one or more actions. An action represents a single step within an activity where data manipulation or processing occurs in a modeled system. "Single step" means you don't break down the action into smaller pieces in the diagram; it doesn't necessarily mean the action is simple or atomic. For example, actions can be:
  • Mathematical functions
  • Calls to other behaviors (modeled as activities)
  • Processors of data (attributes of the owning object, local variables, etc.)
Translating these into real examples, you can use actions to represent:
  • Calculating sales tax
  • Sending order information to a shipping partner
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Activities and Actions
Inhaltsvorschau
An activity is a behavior that is factored into one or more actions. An action represents a single step within an activity where data manipulation or processing occurs in a modeled system. "Single step" means you don't break down the action into smaller pieces in the diagram; it doesn't necessarily mean the action is simple or atomic. For example, actions can be:
  • Mathematical functions
  • Calls to other behaviors (modeled as activities)
  • Processors of data (attributes of the owning object, local variables, etc.)
Translating these into real examples, you can use actions to represent:
  • Calculating sales tax
  • Sending order information to a shipping partner
  • Generating a list of items that need to be reordered because of low inventory
When you use an activity diagram to model the behavior of a classifier, the classifier is said to be the context of the activity. The activity can access the attributes and operations of the classifier, any objects linked to it, and any parameters if the activity is associated with a behavior. When used to model business processes, this information is typically called process-relevant data . Activities are intended to be reused within an application, and actions are typically specific and are used only within a particular activity.
You show an activity as a rectangle with rounded corners. Specify the name of the activity in the upper left. You can show parameters involved in the activity below the name. Alternatively, you can use parameter nodes , described later in this section. Figure 9-1 shows a simple activity.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Tokens
Inhaltsvorschau
Conceptually, UML models information moving along an edge as a token. A token may represent real data, an object, or the focus of control. An action typically has a set of required inputs and doesn't begin executing until the inputs are met. Likewise, when an action completes, it typically generates outputs that may trigger other actions to start. The inputs and outputs of an action are represented as tokens .
Each edge may have a weight associated with it that indicates how many tokens must be available before the tokens are presented to the target action. You show a weight by placing the keyword weight in curly brackets ({}) equal to the desired number of tokens. A weight of null indicates all tokens should be made available to the target action as soon as they arrive. For example, Figure 9-12 shows that nine players are needed before you can make a baseball team.
Figure 9-12: Activity diagram with edge weights
In addition to weights, each edge may have a guard condition that is tested against all tokens. If the guard condition fails, the token is destroyed. If the condition passes, the token is available to be consumed by the next action. If a weight is associated with the edge, the tokens aren't tested against the guard condition until enough tokens are available to satisfy the weight. Each token is tested individually, and if one fails, it is removed from the pool of available tokens. If this reduces the number of tokens available to less than the weight for the edge, all the tokens are held until enough are available. You show a guard condition by putting a boolean expression in brackets ([]) near the activity edge. Guard conditions are typically used with decision nodes to control the flow of an activity (see "Decision and merge nodes").
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Activity Nodes
Inhaltsvorschau
UML 2.0 defines several types of activity nodes to model different types of information flow. There are parameter nodes to represent data being passed to an activity, object nodes to represent complex data, and control nodes to direct the flow through an activity diagram.
You can represent parameters to an activity or output from an executed activity as parameter nodes . You show a parameter node as a rectangle on the boundary of an activity, with the name or description of the parameter inside the rectangle. Input parameter nodes have edges to the first action, and output parameter nodes have edges coming from the final action to the parameter node. Figure 9-13 shows an example of wood being fed into a paper production activity, and paper being produced at the end.
Figure 9-13: Activity diagram with incoming and outgoing parameters
To represent complex data passing through your activity diagram, you can use object nodes. An object node represents an instance of a particular classifier in a certain state. Show an object node as a rectangle, with the name of the node written inside. The name of the node is typically the type of data the node represents. Figure 9-14 is an activity diagram showing a factory producing parts for shipping.
Figure 9-14: Object nodes in an activity diagram
If the type of data the node represents is a signal, draw the node as a concave pentagon. See Figure 9-37 in "Interruptible Activity Regions" for an example of a signal in an activity diagram.
UML defines a special notation for object nodes, called pins , to provide a shorthand notation for input to or output from an action. For example, because the action
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Advanced Activity Modeling
Inhaltsvorschau
UML 2.0 introduces several powerful modeling notations for activity diagrams that allow you to capture complicated behaviors. Much of this new notation is clearly targeted at moving closer to executable models, with things such as executable regions and exception handling. While not all the notations described in this section are used in every model, these constructs are invaluable when applied correctly.
There are times when it is helpful to indicate who (or what) is responsible for a set of actions in an activity diagram. For example, if you are modeling a business process, you can divide an activity diagram by the office or employee responsible for a set of actions. If you are modeling an application, you may want to split an activity diagram based on which tier handles which action. You split an activity diagram using an activity partition. Show an activity partition with two parallel lines, either horizontal or vertical, called swimlanes , with the name of the partition in a box at one end. Place all nodes that execute within the partition between the two lines. Figure 9-25 shows an activity diagram partitioned by business unit.
There are times when trying to draw a straight line through your activity diagram may not be possible. You can show that a node is part of a partition by writing the partition name in parentheses above the name of the node. If the activities within
Figure 9-25: Activity diagram divided into partitions
a partition occur outside the scope of your model, you can label a partition with the keyword «external». This is frequently used when performing business modeling using activity diagrams. If the behavior being modeled is handled by someone external to your business process, you can mark the functionality with an external partition. Figure 9-26 shows examples of naming partitions directly on the node and using external partitions.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 10: Interaction Diagrams
Inhaltsvorschau
A fundamental goal of UML 2.0 is to allow users to capture more than just structural relationships. UML 2.0 is intended to capture processes and flows of events. Interaction diagrams draw from nearly every other facet of the language to put together a set of diagrams that capture communications between objects. UML 2.0 has greatly expanded UML 1.x's ability to describe complex flow of control; one of the largest sections of the UML 2.0 specification is the interaction diagrams section. Because of the expanded functionality, quite a bit of new terminology has been introduced. We'll cover all the terms in this chapter and try to give you a feel for what terms are really critical and which are there to formalize the specification.
Interaction diagrams are defined by UML to emphasize the communication between objects, not the data manipulation associated with that communication. Interaction diagrams focus on specific messages between objects and how these messages come together to realize functionality. While composite structures show what objects fit together to fulfill a particular requirement, interaction diagrams show exactly how those objects will realize it.
Interaction diagrams are typically owned by elements in the system. For example, you may have an interaction diagram associated with a subsystem that shows how the subsystem realizes a service it offers on its public interface. The most common way of associating an interaction diagram with an element is to reference the interaction diagram in a note attached to the element.
You can show the details of an interaction using several different notations; however sequence diagrams are by far the most common. Other notations include interaction overviews, communication diagrams, timing diagrams, and interaction tables. Because sequence diagrams are used most frequently, each concept is introduced using that notation. The other notations are described in detail later in the chapter. The basic symbol for an interaction diagram is a rectangle with the keyword
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
What Are Interactions?
Inhaltsvorschau
Interaction diagrams are defined by UML to emphasize the communication between objects, not the data manipulation associated with that communication. Interaction diagrams focus on specific messages between objects and how these messages come together to realize functionality. While composite structures show what objects fit together to fulfill a particular requirement, interaction diagrams show exactly how those objects will realize it.
Interaction diagrams are typically owned by elements in the system. For example, you may have an interaction diagram associated with a subsystem that shows how the subsystem realizes a service it offers on its public interface. The most common way of associating an interaction diagram with an element is to reference the interaction diagram in a note attached to the element.
You can show the details of an interaction using several different notations; however sequence diagrams are by far the most common. Other notations include interaction overviews, communication diagrams, timing diagrams, and interaction tables. Because sequence diagrams are used most frequently, each concept is introduced using that notation. The other notations are described in detail later in the chapter. The basic symbol for an interaction diagram is a rectangle with the keyword sd and the name of the interaction in a pentagon in the upper-left corner. Figure 10-1 shows an example sequence diagram. The various parts of this diagram are explained throughout the chapter.
Figure 10-1: A sample sequence diagram
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Interaction Participants
Inhaltsvorschau
You show participants in an interaction using a rectangle called a lifeline. The term lifeline illustrates UML's bias toward representing interaction diagrams using the sequence diagram notation. When shown in sequence diagrams, participants have a dashed line dropping down from a rectangle that shows how long the object is actually in existence. When used in other interaction diagram notations, such as communication diagrams, a lifeline is simply a rectangle. You show the name of the participant in the rectangle using the following notation:

            

    object_name [ selector ] : class_name ref decomposition

         
where:
object_name
Specifies the name of the instance involved in the interaction.
selector
Is an optional part of the name that can identify which particular instance in a multivalued element is to be used (for example, which EventHandler in an array of EventHandlers).
class_name
Is the name of the type of this participant.
decomposition
Is an optional part of the name that can point to another interaction diagram that shows details of how this participant processes the messages it receives (see "Decomposition").
UML defines a reserved participant name, self, that indicates the participant is the classifier that owns this interaction diagram.
Figure 10-2 shows a trivial interaction diagram with two participants and a message between them.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Messages
Inhaltsvorschau
The focus of interaction diagrams is on the communication between lifelines. This communication can take many different forms: method calls, sending a signal, creating an instance, destroying an object, etc., all of which are collectively called messages . A message specifies the kind of communication, its sender, and its receiver. For example, a PoliceOfficer class instantiating a SpeedingTicket class is represented as a message from an instance of PoliceOfficer to the newly created instance of SpeedingTicket.
The most common use of messages is to represent method calls between two objects. When messages are used to indicate a method call, you can show the parameters passed to the method in the message syntax. The parameters should be one of the following:
  • Attributes of the sending object
  • Constants
  • Symbolic values (expressions showing what the legal values can be)
  • Explicit parameters of the enclosing interaction
  • Attributes of the class owning the enclosing interaction
The syntax for a message is:

            

    attribute = signal_or_operation_name (arguments) : return_value

         
where:
attribute
Is an optional part of the syntax that provides a shorthand way of showing that the return value from this message is stored in the specified attribute. The attribute must be an attribute of the lifeline sending the message, a global attribute of the interaction, or an attribute of the class owning the interaction.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Execution Occurrences
Inhaltsvorschau
You can show an object is involved in executing some type of action (typically a method call) for a measurable amount of time using an execution occurrence. Execution occurrences are shown as gray or white rectangles on a lifeline. In practice, it is common to hear execution occurrences called "focus of control," because they indicate that an object is busy (has the focus of the system) for some period of time. Figure 10-12 shows several execution occurrences in response to messages.
Figure 10-12: Several example execution occurrences
While not officially part of the specification, it was a common practice in UML 1.x to show messages starting from an execution occurrence on a lifeline to indicate that an object will send messages to other objects as part of processing a received message. With UML 2.0, it may be more appropriate to show a set of messages as an interaction fragment. Using interaction fragments, an appropriate interaction operator, and a reasonable name, you have much greater flexibility in expressing exactly how a piece of the system executes and how it fits into the bigger picture. See "Combined Fragments" for more information on interaction fragments and the various ways you can organize messages to increase your diagram's readability.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
State Invariants
Inhaltsvorschau
UML allows you to place labels along a lifeline to convey conditions that must be true for the remainder of the interaction to be valid. These conditions are called state invariants . State invariants are typically boolean expressions, though they may be full UML states (see Chapter 8). For example, you may have a series of messages that initialize a participant. After the messages have completed, the participant must be in a well-known state for the remainder of the interaction to complete successfully. You can enforce that by placing a state invariant on your diagram after the initialization messages.
You show a boolean state invariant by simply placing the conditional inside curly braces ({}) on the lifeline of the object you want to check. The invariant will be evaluated after any messages that come above it on the diagram. Figure 10-13 shows a basic boolean invariant checking that an Account has been authenticated successfully.
Figure 10-13: A state invariant ensuring that the account is in the proper state before continuing
You show an invariant as a UML state by simply drawing the state symbol (rectangle with rounded sides) over the appropriate part of the lifeline of the object you want to check. The actual information that is validated by the state can be expressed using the normal UML state diagram notation. Figure 10-14 shows the same Account authentication using a UML state.
UML allows you to place the state invariant information inside a note and link it back to the lifeline, though this doesn't tend to be as obvious to the reader as seeing a constraint directly on the lifeline in the proper sequence. Figure 10-15 shows a state invariant using a note.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Event Occurrences
Inhaltsvorschau
Event occurrences are the smallest building blocks of interaction diagrams; they represent moments in time when something happens. Sending and receiving a message are the most common types of event occurrences, though technically they can be any action associated with an object. For example, if object1 sends a message to object2, there are two event occurrences, a message send and a message receive. UML carefully defines interaction fragments as a set of event occurrences where ordering is significant because they represent events over time.
Each type of interaction diagram notation (sequence, communication, etc.) has a way of expressing the time-sensitive nature of the event occurrences. In a sequence diagram the event occurrences are ordered along the lifelines and are read from top to bottom. Figure 10-16 shows a sequence diagram with three of the event occurrences labeled (as mentioned earlier, any action associated with an object is an event occurrence, but to keep the diagram from getting out of control only three are labeled in the figure).
Figure 10-16: A sequence diagram with three event occurrences labeled
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Traces
Inhaltsvorschau
UML defines a trace as a sequence of event occurrences. The term trace is used when discussing sets of event occurrences and how they may be combined. Interaction diagrams allow you to combine fragments in such a way that the event occurrences are interleaved. This combined set of event occurrences is considered a new trace.
Throughout this chapter we will refer to a sequence of event occurrences as event occurrences rather than as a trace to try and reduce the number of keywords.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Combined Fragments
Inhaltsvorschau
Often there are times when a particular sequence of event occurrences has special constraints or properties. For example, you may have a critical region within your interaction where a set of method calls must execute atomically, or a loop that iterates over a collection. UML calls these smaller pieces interaction fragments.
Interaction fragments by themselves aren't terribly interesting, however UML allows you to place them in a container called a combined fragment (it's called a combined fragment even if you have only one interaction fragment in there). Once they are placed in such a container, UML allows you to specify additional detail for each fragment, or how several fragments relate to each other.
Each combined fragment is made up of an interaction operator and one or more interaction fragments, which are the interaction operands. An interaction operator specifies how the interaction operands should be interpreted. The various interaction operators are described in detail later in this chapter.
As you do with full interactions, you show a combined fragment as a rectangle, with the interaction operator in a pentagon in the upper left and the interaction operands inside the rectangle. Figure 10-17 shows a combined fragment representing a critical section of code. The code must be executed atomically because of the interaction operand critical. This and other interaction operators are described in "Interaction Operators."
Figure 10-17: An example combined fragment
Depending on the interaction operator you choose for a combined fragment, you may need to specify multiple operands. You separate operands using a horizontal dashed line across the rectangle. Messages aren't permitted to cross between interaction fragments. The order of the operands is significant for some of the operators, so always read a combined fragment from top to bottom. See Figure 10-18 for an example of multiple operands.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Interaction Occurrences
Inhaltsvorschau
An interaction occurrence is shorthand for copying one interaction into another, larger interaction. For example, you can create an interaction that simply shows user authentication and then reference it (create an interaction occurrence) in larger, more complete interaction diagrams.
The syntax for an interaction occurrence is a combined fragment rectangle with the interaction operator ref. Place the name of the referenced interaction in the rectangle. UML allows parameters to be passed to referenced interactions using the following syntax:

            

    attribute_name = collaboration_occurrence.interaction_name ( arguments ) : return_value

         
where:
attribute_name
Is an optional part of the syntax that specifies what attribute the return value should be applied to. The attribute must be an attribute of a lifeline in the larger interaction.
collaboration_occurrence
Is an optional scoping of the referenced interaction if it is part of a larger collaboration.
interaction_name
Is the name of the interaction to copy.
arguments
Is a comma-separated list of arguments to pass to the referenced interaction. The arguments may be values or parameter names. If only argument values are used, arguments are matched against the interaction parameters, in order. If you want to skip an argument, you place a dash (-) where the argument would be. Skipped arguments have unknown values. You may explicitly identify a parameter name by following its text name with a colon (:) and then the value. If you use parameter names, you may omit arguments not relevant to the interaction. As with a dash, skipped arguments have unknown values.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Decomposition
Inhaltsvorschau
A participant in an interaction diagram may be a complex element in and of itself. UML allows you to link interaction diagrams by creating a part decomposition reference from a participant to a separate diagram. For example, you may have a Purchase Item interaction diagram that has a participant execute a credit card authorization. The actual details of the authorization process are probably not of interest to the readers of your Purchase Item diagram; however, they are vitally important to the developers responsible for the authorization subsystem. To help reduce clutter on your diagrams, you can create a separate diagram showing how the authorization subsystem validates credit cards and place a decomposition reference to that on the Purchase Item diagram.
To create a part decomposition reference, simply place ref interaction_diagram_name after the instance name in the head of your lifeline. Figure 10-31 shows how the Purchase Item and authorization diagrams can be modeled.
Figure 10-31: Example of a decomposition diagram
Messages that come into or out of the decomposed lifeline are treated as gates that must be matched by corresponding gates on the decomposition. A gate represents a point where a message crosses the boundary between the immediate interaction fragment and the outside environment. A gate has no symbol of its own; you simply show a message pointing to the edge of the frame of an interaction fragment. The entire purpose of a gate is to show an object that sent a message connecting to the object that received the message.
By default, a gate's name is based on the direction (in or out) and the message in question. For example, a gate showing a message named
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Continuations
Inhaltsvorschau
Typically used with interaction references, continuations allow you to define different branches of an alternative interaction outside of the alternative itself. Continuations are conceptually similar to named blocks of functionality.
The notation for continuations can be particularly confusing. You show a continuation using the symbol for states, a rectangle with rounded sides; however, the position of the rectangle changes the meaning of the diagram. You place a continuation at the beginning of an interaction to define the behavior for that continuation. You use a continuation by showing the rectangle at the end of an interaction. Finally, continuations with the same name must cover the same lifelines (and only those lifelines).
Figure 10-34 shows the first of three sequence diagrams demonstrating a continuation; this one displays the details of a Login sequence. After the password is retrieved from the database, an alternative interaction is entered. If the passwords match, various flags are set on the UserCredentials. After setting the flags, there is a continuation named Login success, in which users of this sequence diagram can plug in their own functionality. If the passwords don't match, the else part of the alternative interaction executes, which leads to the Login failed continuation. Notice the continuation symbols are at the end of each interaction operand, indicating this diagram uses an externally defined continuation.
Figure 10-34: Using a continuation in a sequence diagram
Figure 10-35 shows the second diagram, a sequence diagram that makes use of the Login sequence and defines continuations for Login success and Login failed. If the correct password was entered, the Login success continuation is executed; otherwise, the Login failed continuation is run. Notice in this diagram that the continuation symbols are at the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Sequence Timing
Inhaltsvorschau
UML provides a notation to capture a specific time associated with an event occurrence. You simply place a small horizontal line next to an event occurrence to capture the time of the occurrence, or place a timing constraint on it. Typically, you use a variable to capture a specific instance in time and then represent constraints as offsets from that time. Constraints are expressed like state invariants and placed next to the event occurrence.
For example, if you want to express that a credit card authorization system must return approval or denial within three seconds of placing the request, you can place time constraints on the event occurrence, as shown in Figure 10-37.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Alternate Interaction Notations
Inhaltsvorschau
UML provides several notations for capturing interactions. The first part of this chapter used the sequence diagram notation. The remainder of this chapter describes the other notations available and when they may be more appropriate than sequence notation.
Figure 10-36: The final sequence, with all continuations expanded
Communication diagrams allow you to focus on the elements involved in interactions rather than the detailed sequencing and flow control allowed in sequence diagrams. Most UML tools can automatically convert from a sequence diagram to a communication diagram; however, because communication diagrams aren't as expressive,.some information may be lost.
When you're modeling with communication diagrams, objects are represented by a rectangle, and connections between objects are shown as a solid line. Each message has a sequence number and a small arrow indicating the direction of the message along a given connection. Communication diagrams can't show message overtaking (see Figure 10-6 earlier in the chapter) or interaction fragments.
Figure 10-38 shows a simple sequence diagram and the equivalent communication diagram.
The syntax for a message name is:

               

    sequence_number: name [ recurrence_or_guard ]
Figure 10-37: A sequence diagram with hard timing requirements
Figure 10-38: Example of a sequence diagram and its equivalent communication diagram
where:
sequence_number
Is the index of the message with 1 being the index of the first message in the diagram. You show nested message calls by appending the original message number with a decimal and then starting a new sequence. For example, if the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 11: Tagged Values, Stereotypes, and UML Profiles
Inhaltsvorschau
The UML described in the previous chapters allows you to understand any UML model. You can understand the analysis of a billing system, the implementation model of a CORBA system, a gaming system in C++, or an EJB e-commerce system.
Practitioners rarely work on such diverse systems at one time, however, and no UML model will represent more than one type of application. More commonly, a practitioner (that's you) works with colleagues on one system or a series of closely related systems exclusively. For example, you might design a series of gaming systems, or a series of .Net systems. And, as you might expect, the specific concerns of a gaming system differ profoundly from those of a .Net system.
UML allows toolmakers to create a dialect called a profile, tailored to a specific niche. Within a niche, a stereotype gives specific roles to elements, and records additional context-specific information in tagged values. Profiles also include constraints that ensure integrity of use.
A practitioner familiar with a profile will immediately grasp the meaning of a model developed using that profile, because of the unique stereotypes. Moreover, the model contains deeper meaning, because of the tagged values, and the model has a higher degree of integrity, because of the constraints. This gives a distinct advantage to practitioners and tools working in the niche. People and tools unfamiliar with the profile will process it only at a formal level, without any special understanding.
Profiles are the standard mechanism to extend UML. The profile mechanism exists within UML so models applying a profile are fully UML compatible. This contrasts sharply with implementors' extensions in loosely specified languages such as C++, in which the specification allows inline assembler and #pragma statements, making it virtually impossible to port C++ programs between processors or between different compilers. A UML model applying a profile is UML, and any UML tool can process it.
Although a plethora of dialects can fragment the universality of UML, a dialect makes UML more useful. And isn't that what it's all about?
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Modeling and UML in Context
Inhaltsvorschau
Throughout the evolution of modeling, practitioners, implementors, academics, and other interested parties have found new and innovative ways to model, and new disciplines to model. It soon became apparent that the generality of the canonical UML was not concise enough for practitioners working full time in a particular language, technology, or platform, such as ANSII C++, Struts, or .Net. Moreover, practitioners in similar disciplines, such as process engineering, with different fundamental structures and constraints found UML interesting but not quite appropriate. They can better benefit from a UML-like language other than UML itself. Figure 11-1 illustrates this situation, where the Meta-Object Facility (MOF), explained more fully later in the chapter, comprises all UML models as well as UML-like models.
Figure 11-1: The universe of valid models in UML family
The authors of UML could have specialized UML for common programming languages (such as C++, C#, Java, and Visual Basic) and platforms (such as embedded systems, real-time operating systems (RTOS), EJB, and .NET). This would have created an unworkable modeling language, as each programming language or dialect polluted the specification with conflicting definitions. It would still require an extension mechanism because some "uncommon" language (such as Smalltalk) or new platform/technique or version (like EJB 3.0) would always be missing from the formal specification.
On the other hand, the authors could have stretched UML to greater abstraction to embrace uses other than software development, such as business modeling, modeling the process of software development itself, or modeling systems engineering. This would have made everything even more abstract. Because designers work in only one specific domain, abstraction impedes concise expression, moving the models further from their domains.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Stereotypes
Inhaltsvorschau
Stereotypes modify the intent of the elements to which they apply. They allow the differentiation of roles of an element within the model. For example, you can quickly differentiate classes stereotyped as Controller as having a different role in the system than those stereotyped as View.
Visually, UML allows graphical and textual representation of a stereotype. Graphics and text can be combined in various ways for node-type elements, as shown in Figure 11-3. The four elements that you see going across the top of the figure all represent the same combination of Form and key stereotypes but in different ways. Edge-type elements have only a textual representation, and thus you see «depends» on the dependency between Billing and Inventory.
Figure 11-3: Various representations of stereotypes
When displayed as text, a stereotype is enclosed in guillemots («»), as in «MyStereotype». Because the guillemots require an extended character set to display correctly, you may also use double angle brackets to show a stereotype in 7-bit ASCII, as in <<MyStereotype>>.
Graphical icons are neither defined nor standardized by UML. You can expect toolmakers to extend the graphics differently, including coloring or shading, at their discretion. Avoid graphical symbols for interchange of models between different tools. However, within the controlled environment of a compatible set of tools, specialized graphics and/or colors will likely have more visual impact.
While stereotypes have been around since the initial beta versions of UML, UML 2.0 has introduced significant changes to the 1.x versions:
  • Elements may have zero, one, or more than one stereotype. The use and usefulness of stereotypes have become more and more evident. More toolmakers have incorporated them into their products. Modelers found it impossible to use otherwise complimentary tools because an element can have only one stereotype.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Tagged Values
Inhaltsvorschau
Having established an element's role within a system with a stereotype, the element likely needs information not available from the core UML, to fulfill its role. The stereotype defines a number of tagged values. Each tagged value is typed with a datatype—number, string, boolean, or user-defined enumeration. The upcoming section "UML Profiles" shows one way in which you might record, or define, the tagged values that you wish to include in a stereotype.
When you show them in a diagram, place the tagged values in a note element that is connected to the declaring element with a dashed line. Figure 11-5 shows the case of multiple stereotypes on one element. To keep the stereotypes and the corresponding tagged values clear, each stereotype is mentioned, and the tagged are values listed separately.
Figure 11-5: Tagged values shown classified by their owning stereotype
At first, you may confuse tagged values with attributes, but they exist at a different level of abstraction. Attributes, defined in the design model (M1), exist in the runtime system (M0). Tagged values, defined in the profile (M2), exist only in the design model (M1). The tagged values may provide hints to help the generation of code, either by human or machine. A tagged value of {optimize=space} will probably affect the code ultimately, although the actual value itself never appears in the code.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Constraints
Inhaltsvorschau
Stereotypes give roles to elements. Tagged values provide role-specific information enriching the element in its role. While atomically the element knows its role and has all the information to fulfill it, the element must still interact with its neighbors. The element and their roles must be in harmony with the architectural vision. The element must also be internally consistent. Constraints (see "Constraints" in Chapter 2) provide the mechanism to specify rules for correct usage of the stereotyped elements.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
UML Profiles
Inhaltsvorschau
UML profiles combine the concepts of stereotypes, tagged values, and constraints to provide a coherent and concise dialect of UML for a specific family of applications. To make much use of a profile, some tooling must be provided. The application model drives code or application generation, so you have little or no control over the stereotypes, tagged values, or constraints comprising the profile. This section discusses the use of existing profiles (as opposed to defining your own).
Figure 11-6 depicts a partial UML profile defining a stereotype with its associated tagged values and a couple of constraints, as you might receive in a vendor's documentation. The profile extends classes with a stereotyped class, «EJBEntityBean». It extends attributes with two stereotyped attributes: «EJBPrimaryKey» and «EJBCmpField». It declares the respective tagged values for the stereotyped classes and attributes, and it declares the enumeration, TransactionIsolationLevel, to define the allowable values for the TransactionAttribute tagged value. The profile also adds the constraints that «EJBEntityBean» classes must have attributes of type «EJBCmpField» and «EJBPrimaryKey». Furthermore, attributes having these stereotypes can exist only in an «EJBEntityBean» class. From your point of view, the profile, along with its constituent stereotypes and tagged values, is read-only because it tells what the third-party tool expects in order to do its job.
Figure 11-6: A partial specification UML profile
Figure 11-7 shows a portion of a model using the profile declared in Figure 11-6. Figure 11-8 indicates how the tagged value structures in the model relate back to the profile declaration. The notes containing the tagged values make the notation bulky if you need to show a set of tagged values for every class, attribute, operation, and relationship.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Tools and How They Use Profiles
Inhaltsvorschau
UML tools use profiles to provide a spectrum of solutions. Tools providing Model-Driven Architecture (MDA) solutions have transformations from the Platform-Independent Model (PIM) to Platform-Specific Model (PSM) and from the PSM to the application. See Appendix A for a fuller discussion of MDA.
The OMG conceived the MDA as a vision rather than a specified method. Each vendor has a different, sometimes radically different, approach to MDA. Consequently, although the concepts of the PIM and the PSM vary greatly from one vendor to another, any one vendor's concept of the PIM and the PSM is strict and concrete. The extra roles and information, introduced as the PIM is refined to the PSM and the PSM to code, must be well defined and well controlled. Profiles provide the definition of the information to be captured and the constraints on a valid model. Each tool validates conformity to a profile in its own way. The PIM needs only one profile because it can be used and reused for different platforms. Each PSM, on the other hand, potentially needs a different profile because each specific platform has different issues and transformations to arrive at optimal code.
Tools previous to MDA still use profiles. In general, they provide a model-to-code code generation feature and often a code-to-model reverse engineering feature. To faithfully generate runnable code, many details must be stored in the model. Many language-dependent features can't be recorded in core UML. For example, UML doesn't recognize the Java keyword strictfp, which indicates floating-point processing. Without tagged values, a reverse-engineered system would not faithfully reproduce the same code when forward engineered.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 12: Effective Diagramming
Inhaltsvorschau
This chapter illustrates how you can create effective class diagrams. The diagrams presented in the reference section of this book have few elements. Those diagrams illustrate individual diagram elements, clear of any clutter; they aren't meant to illustrate diagram types. The diagrams in the reference section don't represent systems that you will encounter in real life. This final chapter illustrates some techniques you can use to make real-life diagrams convey your thoughts more effectively.
The classic novice class diagram displays all classes, attributes, operations, relationships, and dependencies for a system. As the number of classes grows, the diagram becomes huge and unmanageable. Imprudent reverse engineering drags in clutter. Figure 12-1 diagrams just a very small part of the Java Abstract Windowing Toolkit (AWT). You will not be able to read the diagram because it normally prints as an unwieldy nine pages. You're paying for the paper, so the diagram is shown here in a greatly condensed form.
Effective writers convey ideas through language constructs: sentences and paragraphs organize text, details reinforce ideas, and true but irrelevant facts are omitted. Modelers desiring to convey an idea—be it a structural overview, a pattern implementation, a detailed subsystem, or the detailed context of one class—must also use economy and focus. Figure 12-1 has neither economy nor focus. The diagram throws a mass of insignificant detail at readers, leaving the burden of understanding on them. It is a false economy to think that one diagram can present all the information of a multidimensional model.
Figure 12-1: An overloaded and ineffective class diagram
Before making Figure 12-1 more effective, let's distinguish modeling from diagramming. The act of modeling furthers your understanding of the system under study. You use diagrams to elaborate the model. You confirm the model integrity with new views. You organize your understanding. You extend your knowledge. You challenge your understanding. By seeing the known, you can infer, dictate, or investigate the yet to be known. Figure 12-1 might be seen during modeling, but only as an intermediate step; such diagrams don't demonstrate UML's true power to communicate.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Wallpaper Diagrams
Inhaltsvorschau
The classic novice class diagram displays all classes, attributes, operations, relationships, and dependencies for a system. As the number of classes grows, the diagram becomes huge and unmanageable. Imprudent reverse engineering drags in clutter. Figure 12-1 diagrams just a very small part of the Java Abstract Windowing Toolkit (AWT). You will not be able to read the diagram because it normally prints as an unwieldy nine pages. You're paying for the paper, so the diagram is shown here in a greatly condensed form.
Effective writers convey ideas through language constructs: sentences and paragraphs organize text, details reinforce ideas, and true but irrelevant facts are omitted. Modelers desiring to convey an idea—be it a structural overview, a pattern implementation, a detailed subsystem, or the detailed context of one class—must also use economy and focus. Figure 12-1 has neither economy nor focus. The diagram throws a mass of insignificant detail at readers, leaving the burden of understanding on them. It is a false economy to think that one diagram can present all the information of a multidimensional model.
Figure 12-1: An overloaded and ineffective class diagram
Before making Figure 12-1 more effective, let's distinguish modeling from diagramming. The act of modeling furthers your understanding of the system under study. You use diagrams to elaborate the model. You confirm the model integrity with new views. You organize your understanding. You extend your knowledge. You challenge your understanding. By seeing the known, you can infer, dictate, or investigate the yet to be known. Figure 12-1 might be seen during modeling, but only as an intermediate step; such diagrams don't demonstrate UML's true power to communicate.
Diagramming, on the other hand, expresses understanding for the benefit of others. You may be a domain expert by background, or you may have recently synthesized expertise from modeling with domain experts. You have worked hard to understand, and to put your understanding into a model, perhaps over weeks or months; now you must make that understanding immediately accessible to your readers. Your model should be concise so that they understand. If there is to be contention, let it be about real ideas, not ambiguity.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Sprawling Scope
Inhaltsvorschau
Figure 12-5 shows an example of a poorly focused sequence diagram. Sequence diagrams risk taking on too many interactions at once. This one shows the Struts interactions, the application interactions, and then the detailed workings of the Java libraries.
Figure 12-5: Sequence diagram of HTTP form processing, spanning Struts, application, and java.lang
Elements at the high and low end of this diagram are clearly out of scope of the application. One rarely cares how Struts, as an off-the-shelf framework, works. It calls the application logic at the appropriate time. Similarly, just how the internals of the standard libraries carry out their obligations normally doesn't matter in terms of understanding the application. Both the structure of HTTP request processing and the workings of Strings are God-given as far as the application developer is concerned. However, by showing a few elements that are out of scope, the diagram allows you to see the context of the application within the greater framework, and that's often useful when selecting an architecture. Similarly, drilling down into the base libraries exposes thread or performance issues. These are exceptional needs; there is no call to complicate the description of an application with these exploratory needs. From the readers' point of view, nonapplication elements just cloud understanding of the business logic, the only thing over which the developer exerts control.
Figure 12-6 shows the processing for another HTML form. It gets to the point. It is concise enough for one page. And it focuses on interactions between the application classes; the interactions are under control of the development team.
Figure 12-6: Sequence diagram with scope restricted to programmer-defined classes
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
One Diagram/One Abstraction
Inhaltsvorschau
Earlier, in Figures 12-2 and 12-3, we separated structure from inheritance. Each diagram contains fewer elements than the all-encompassing diagram shown in Figure 12-1, or even the more modest one shown in Figure 12-2, so they are easier to understand. Figure 12-7 shows package dependencies. The diagram records both the import graph and code generation directives. The superimposition of these two roles results in a diagram with pairs of opposing dependencies between elements. Don't worry if you don't quite understand its meaning; we'll clean it up in a moment.
Figure 12-7 fails as a diagram for several reasons. Most strikingly, you don't know where to start: the diagram has no center of gravity. This leads to a lack of flow or direction; do you read the diagram left to right, top to bottom, or inside out? The apparently cyclic dependencies confound any sense of direction. Although opaque to the initiated, the problem with Figure 12-7 stems from trying to use one diagram for two related but different ends: controlling imports and directing code generation.
Figure 12-7: Package diagram controlling imports and code generation directives
Figure 12-8 addresses the issue of imports only. Elements higher in the diagram depend on elements below. No cycles exist. You can absorb the meaning of the diagram quickly.
Removing the imports from Figure 12-7 simplifies it more than you might imagine. Instead of forming a graph like the imports, the directives, as shown in Figure 12-9, just link separate elements with target packages. The noise of the import graph complicated a simple picture. The complicated, large diagram becomes a small diagram of four separate sections.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Besides UML
Inhaltsvorschau
UML provides description that's difficult to match with plain text. Its formalism allows a few lines and boxes to unequivocally and immediately convey what would require time to assimilate from text. The text replaced by diagrams would be, at best, dull and legalistic, and at worst, vague, ambiguous, and open to interpretation. Either way, well-written UML is more effective.
While it may be true that a picture is worth a thousand words, a picture with words is worth much more than just a picture. Perhaps in the context of MDA and executable models, UML can provide a minimum specification for an application generator. In most cases, complete system specification or system documentation requires commentary to explain, emphasize, and give nuance to the diagrams. Diagrams alone risk burying or glossing over details as much as text alone. Diagrams and text reinforce each other. You can describe the context and
Figure 12-8: Package imports
major points with text, then drive home those points with a good diagram and the formalism of UML.
As seen throughout this chapter, you can't effectively document classes with large APIs on a single, class diagram. Hundreds of attributes and operations become insignificant on a diagram. The operation and attribute sections of a class box don't allow for descriptions. Tools such as Doxygen (http://www.doxygen.org) or Javadoc extract the most current source comments into searchable web pages. Though the details they present are likely to change and therefore will make diagrams obsolete, when they are made part of the software build process, they remain up to date with the latest software changes.
Remember that diagramming requires neither model nor modeling tool. UML practitioners often simply draw diagrams by hand or with simple drawing tools. Modeling tools are expensive acquisitions, in terms of time and distraction, if not in money: open source or proprietary, UML tools take time to master. Whiteboards, notepads, and simple drawing tools deliver much project value with no learning curve. Use them until you are comfortable with UML and its place in the project. With a firm understanding of UML and your process, choosing a dedicated UML tool and changing your process to incorporate it becomes less risky.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Appendix A: MDA: Model-Driven Architecture
Inhaltsvorschau
This appendix summarizes Model Driven Architecture (MDA). Several authors dedicate whole books to MDA; seek out those books. The treatment here aims simply to demystify MDA enough so that you can talk sensibly about it. Better yet, investigate the vendor offerings. Abstract descriptions don't deliver value: tools do.
Both Model Driven Architecture and MDA, like the Unified Modeling Language and UML, are trademarks of the Object Management Group.

Section A.1: What Is MDA?

Section A.2: The Models of MDA

Section A.3: Design Decisions

Section A.4: Sewing the Models Together

Section A.5: Transforming Models

Section A.6: Languages to Formally Describe MDA

Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
What Is MDA?
Inhaltsvorschau
MDA is the natural evolution of UML, Object Oriented Analysis and Design (OOAD), code generators, and third millennium computing power. At the highest level, MDA envisions the day that UML models become the standard way to design and build software. Business software developers will build their systems through MDA tools. Development in 3GL languages such as Java or .Net will remain a toilsome necessity for the system level. For business applications, current languages will be too inefficient to be viable, used only by the most backward-looking organizations. As an analogy, consider the place of assembler and C (or even C++) in main-line business applications today.
MDA uses models to get the highest leverage out of software development. MDA isn't a development process. It isn't a specification. It isn't an implementation. It isn't a conformance suite. It doesn't have a reference implementation. The OMG, wisely, has avoided specifying how you go about leveraging software models. MDA has not matured, so each of the nearly 50 companies committed to MDA promote vastly differing visions. If you find this confusing, you aren't alone.
MDA defines a framework for processing and relating models. MDA tools transform pure business models into complete, deployable, running applications with a minimum of technological decisions. Modifying the pure business model behind an application require only updates in the dependent technological area(s). Technology decisions unrelated to the change remain, so the application can be regenerated in a matter of a few minutes.
An application has many concerns; some related to the business itself, some related to a particular implementation tier, some related to a particular implementation technology. MDA further separates the technological concerns of an application from the business; it separates high-level technical decisions from their technological implementation; it separates one technology from another. Web forms or database tactics don't complicate the business concepts of, say, Account and Customer. Transaction management decisions don't affect persistence. Messaging doesn't interfere with property management or security. Each technology can be replaced without recoding. In the extreme case, the business application can be redeployed on a completely different technology platform.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
The Models of MDA
Inhaltsvorschau
Models play a big role in MDA. As a framework for building systems, MDA abstracts systems into abstraction layers. Traditionally OOAD had analysis, detailed design and code roughly representing a system's business perspective, the architectural/technological perspective, and the implementation perspective. MDA adds one abstraction on top, representing the business context of the system. Figure A-1 shows the different abstraction layers and their associated MDA models. Abstraction increases toward the left and concreteness increases toward the right. Concrete models outnumber abstract models. In general, the abstract begets the concrete; as each model becomes more concrete, it realizes the abstractions with respect to one technology or platform. The inverse, making abstract models from the concrete, also known as reverse engineering, rarely happens, except when the starting point is code. Even then because the system must support a business, starting from the business needs is generally more appropriate.
Figure A-1: An example of MDA models and their relationship
The abstraction models match well with the conceptual layers of a system:
Computational-independent model (CIM)
The CIM represents the highest-level business model. The CIM uses a specialized business process language and not UML, although its language could well be derived from the meta-object facility (MOF).
The CIM transcends computer systems. Each process interacts with human workers and/or machine components. The CIM describes these interactions between these processes and the responsibilities of each worker, be it human or otherwise.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Design Decisions
Inhaltsvorschau
As you've seen in Figure A-1, the number of models increases as you go from the abstract to the concrete. How abstract models become transformed into more concrete models will be discussed a little later. For now, suffice it to say that some function transforms them. Several concrete models can come from a single abstract model. At any one level of abstraction, the model presents the system, without the messiness of implementation details found in the more concrete, downstream models.
Effective model transformation demands precise implementation details. Decisions at one layer imply gross differences at the next, more concrete layer. Consider the following business rules:
  • There are only a few (50) states, and they don't change.
  • Account transactions can be added, but never changed or deleted, and there can be hundreds of thousands of transactions for one account.
  • Account balances are updated very often, but account contact information is updated relatively rarely compared to the number of times it's read. Changes must be audited.
If similar code were to be generated to manage these data entities, you would have a very poor system. To live up to its moniker, MDA must provide some clue in the business model to differentiate between these cases. The business layer doesn't involve itself with design issues such as data access patterns, but it must provide hints. These hints are design decisions . Models provide implicit hints through the structure (a one-to-one association versus a many-to-one association), and they can be elaborated with explicit hints (such as differentiating the three earlier cases).
At the level of code generation, 3GLs have hints, although they work at a much lower level of abstraction. Programmers switch on code optimization or debugging information. As a result, the bytecode/object code becomes vastly different, with different performance characteristics.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Sewing the Models Together
Inhaltsvorschau
At any one time, the many models are implicitly related. For example, a transformation function transforms the PIM and related marks from a marking model to create a PSM. An MDA system of models probably has several PSMs, each with its own marking model and at least one code model, and likely its own marking model or handcoded extensions.
Over time, the PIM will change, as will the marks on it and on the PSM. If the transformation function summarily overwrites existing marks explicitly updated by a modeler, the effect of the marks disappears; the modeler must reenter all again. Clearly, this is untenable. On the other hand, deletions from the PIM will remove the justification of derived elements in the PSM. The transformation function must have a way to detect and merge collisions, and to remove deadwood. Traceability of ownership and generation becomes a serious issue.
MDA stores the relationships between source models, marks, and target models in a mapping model . The example in Figure A-3 shows how each element in the target model has a mapping to the source model and the appropriate marks (and, optionally, to the marking models).
Figure A-3: Mapping models ensure traceability between the models and the marks
The mappings provide the traceability necessary for subtle evolution of the whole system. The transformation process follows the links when updating a target model from new versions of the source model or source mark model. The transformation function detects conflicts between the generated elements and the existing element added or modified by modelers. It identifies deadwood in the new target model that exists only because of now-deleted elements in the source model.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Transforming Models
Inhaltsvorschau
The models up to now provide multiple abstractions of the system. They separate the platform concerns. They trace the origin of each element. These models are static. Transformation functions apply a transformation to a source model to produce a target model. Figure A-4 shows the general case of the transformation function creating or updating target models from the source model and marks. The transformation function, along with the marks and the mappings, are called the bridge between the two principle models.
The mapping model acts in two roles. Before the transformation, it relates the elements of the source models, together with previous versions of the target models. After the transformation, the mapping model traces the source of every target model element created or updated.
During model evolution, transformations at the PIM can cause turmoil in the PSM and code models. Because of the leverage MDA gives, slight refactoring can render the mapping model incapable of reconciling changes. If mappings are recorded by element ID, deleting an element and recreating it risks orphaning it from its marks
Figure A-4: Custom model transformations automate changing abstraction levels
and derivative elements in the target models. If the PSM or code model has a great deal of elaboration, MDA doesn't proscribe a solution to this.
Figure A-4 shows a transformer acting through a transformation definition. The transformer can be implemented equally well as a script or a procedural language. In any case, each transformation requires its own definition; the transformer from PIM to presentation PSM can't be reused for the database PSM to SQL code model.
The concept of reverse engineering, or round-trip engineering, received a great deal of interest a few years ago. MDA doesn't address it specifically. Each transformation function can have an inverse function to create the abstract from the concrete, but nothing requires an MDA solution to provide it.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Languages to Formally Describe MDA
Inhaltsvorschau
The transformations describe in the preceding section can't work without strict inputs. Each model must respect a structure that constrains its expressiveness formally; automated transformations can't understand just any model. Each model requires a specialized model, as shown in Figure A-5. UML profiles provide one vehicle to constrain each model; alternative MOF-based metamodels provide another.
Explicit UML profiles enforce constraints so that only models considered valid by the transformers can be processed. Considering the leverage of expression between the PIM and each PSM, and again between each PSM and its derivative
Figure A-5: Each model and transformation definition conforms to a language
code models, slightly invalid source models would produce rubbish. UML profiles provide the discipline needed to keep such a complex system running.
MDA systems need not have such a formal definition as the one we described. Certainly architects who extend the transformations with custom scripting will not back it with a formal transformation language. The languages act much as DTDs or schemas do for an XML document: languages assure that the consumers will understand the model.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Appendix B: The Object Constraint Language
Inhaltsvorschau
The Object Constraint Language 2.0 (OCL) is an addition to the UML 2.0 specification that provides you with a way to express constraints and logic on your models. For example, you can use OCL to convey that a person's age must always be greater than 0 or that a branch office must always have one secretary for every 10 employees.
OCL isn't new to UML 2.0; it was first introduced in UML 1.4. However, as of UML 2.0, it was formalized using the Meta-Object Facility and UML 2.0. From a user's perspective the language has been updated and refined but the fundamentals remain the same. This appendix introduces the basic concepts of OCL. For more detailed information, consult the OCL specification available from the Object Management Group's web site (http://www.omg.org/).

Section B.1: OCL Basics

Section B.2: OCL Syntax

Section B.3: Advanced OCL Modeling

Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
OCL Basics
Inhaltsvorschau
The Object Constraint Language is just that: a language. It obeys a syntax and has keywords. However, unlike other languages, it can't be used to express program logic or flow control. By design, OCL is a query-only language; it can't modify the model (or executing system) in any way. It can be used to express preconditions, postconditions, invariants (things that must always be true), guard conditions, and results of method calls.
OCL can be used virtually anywhere in UML and is typically associated with a classifier using a note. When an OCL expression is evaluated, it is considered to be instantaneous, meaning the associated classifier can't change state during the evaluation of an expression.
OCL has several built-in types that can be used in OCL expressions:
Boolean
Must be either true or false. Supports the logical operators and, or, xor, not, implies, and if-then-else.
Integer
Any integer value (e.g., 100, -12345, 5211976, etc.). Supports the operators *, +, -, /, and abs().
Real
Any decimal value (e.g., 2.222003, -67.76, etc.). Supports the operators *, +, -, /, and floor().
String
A series of letters, numbers, or symbols interpreted as a string (e.g., "All writing and no play make Dan..."). Supports the operators concat(), size(), and substring().
In addition to the built-in types, any classifier used in your UML model is recognized as a type by OCL. Because OCL is a strongly typed language, you can't compare values of one type directly with values of another type.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
OCL Syntax
Inhaltsvorschau
The remainder of this chapter uses examples from the class diagram shown in Figure B-1.
Each OCL expression must have some sense of context that an expression relates to. Often the context can be determined by where the expression is written. For example, you can link a constraint to an element using a note. You can refer to an instance of the context classifier using the keyword self. For example, if you had a constraint on Student that their GPA must always be higher than 2.0, you can attach an OCL expression to Student using a note and refer to the GPA as follows:

    self.GPA > 2.0
Figure B-1: Example class diagram used in this chapter
It's important to realize that this OCL expression is an invariant, meaning the system would be in an invalid state if a student's GPA dropped to less than 2.0. If you want to allow a GPA of less than 2.0 and send out a letter to the student's parents in the event such a low GPA is achieved, you would model such behavior using a UML diagram such as an activity or interaction diagram.
You can follow associations between classifiers using the association end names as though they were attributes of the originating classifier. The following invariant on Course ensures that the instructor is being paid:

    self.instructor.salary > 0.00
If an association has a multiplicity of 0..1, you can treat the association end as a Set and check to see if the value is set by using the built-in notEmpty() operation. To call the notEmpty() operation on a set you must use an arrow (->) rather than a dot (.). See "Collections" for more information on sets. The following invariant on Course enforces that a course has an instructor:

    self.instructor->notEmpty()
If an association role name isn't specified, you can use the classifier name. The following invariant on
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Advanced OCL Modeling
Inhaltsvorschau
Like any other language, OCL has an order of precedence for operators, variable declarations, and logical constructs (only for evaluating your expressions, not for program flow). The following sections describe constructs that you can use in any OCL expression.
OCL supports basic boolean expression evaluation using the if-then-else-endif keywords. The conditions are used only to determine which expression is evaluated; they can't be used to influence the underlying system or to affect program flow. The following invariant enforces that a student's year of graduation is valid only if she has paid her tuition:

    context Student inv:

    if tuitionPaid = true then

      yearOfGraduation = 2005

    else

      yearOfGraduation = 0000

    endif
OCL's logic rules are slightly different from typical programming language logic rules. The boolean evaluation rules are:
  1. True OR-ed with anything is true.
  2. False AND-ed with anything is false.
  3. False IMPLIES anything is true.
The implies keyword evaluate the first half of an expression, and, if that first half is true, the result is taken from the second half. For example, the following expression enforces that if a student's GPA is less than 1.0, their year of graduation is set to 0. If the GPA is higher than 1.0, Rule #3 applies, and the entire expression is evaluated as true (meaning the invariant is valid).

    context Student inv:

    self.GPA < 1.0 IMPLIES self.yearOfGraduation = 0000
OCL's boolean expressions are valid regardless of the order of the arguments. Specifically, if the first argument of an AND operator is undefined, but the second operator is false, the entire expression is false. Likewise, even if one of the arguments to an OR operator is undefined, if the other is true, the expression is true
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
	

Zurück zu UML 2.0 in a Nutshell


Themen

Buchreihen

Special Interest

International Sites

O'Reilly China O'Reilly USA O'Reilly Japan O'Reilly Taiwan