Changes in the Updated Edition for UML1.3

The intention is that if you print out this page plus this diagrams referred to, you have an "update pack" which can be applied to a copy of the original edition to get the changes made in the revised edition. I hope that this will help students and lecturers! Thanks to the publishers for permitting me to make this material available.

Not listed here are simple corrections of typos or minor changes to wording. First a title page change:

Q: Why has the list of authors changed?
(from "Rob Pooley and Perdita Stevens" to "Perdita Stevens with Rob Pooley")
A: Don't worry, it's still the same book! Although Rob was fully involved at the beginning of the project, circumstances, chiefly his move to a chair at Heriot-Watt University, meant that I gradually took over more of the project and have been in sole charge of it since the first edition appeared. The title page change is just an update.

Page references here are into the (third printing of the) original edition. (Though there are very few pagination changes, so you should be able to use the pages references in the updated edition too with few problems.)

PageWhere Change Comment
Inside cover L Association class Delete empty compartment in "is taking" UML now specifies that empty compartments are omitted.
Inside cover R Use cases relations between use cases now follow UML1.3
50 Line -4 Objectory -> Unified Process Objectory has been (slightly modified and) renamed the Unified Process.
51 under Other Processes First line -> "Catalysis, [17] is a"; paragraph at bottom of page is deleted (because both [17] and RUP now exist)
52 DQ29 Add bullet points for Catalysis and OPEN
62 l8 always -> normally "always" was too strong: very occasionally a name is not helpful.
62 three lines above 5.2.1 Added new technical UML note:
The definition of association that we use in this book is a dynamic one: if at runtime objects may exchange a message, there must be a navigable association between their classes. Sometimes it is convenient to take a more restrictive static view, in which class A only has a navigable association to class B if an attribute of A contains an object (or collection of objects) of class B. UML does not specify which definition to use: it sometimes refers to static associations as ``real'' or ``actual'' associations, but dynamic associations are also mentioned in UML.
In fact, exactly what one should mean by association is rather an interesting issue... but this clarifies what we mean, at least.
63-73In the rest of Chapter 5 the page breaks come slightly later...
73 Discussion Questions Add as number 5:
Consider the dynamic and static notions of association mentioned in the Technical UML Note in Section 5.2. Construct a small example of classes which are dynamically but not statically associated, and consider the two versions of the UML class diagram you get by adopting either notion. What do you think are the advantages and disadvantages of each convention? What does the absence of an association between classes mean, in each case?
78 After DQ44 Slightly reworded paragraph to:
Now we have a way of showing that it is possible to navigate an association in a certain direction, but we don't have any way to show that it is not possible to navigate it. The obvious thing to do is to say that the absence of an arrow means non-navigability: but the problem with this is that when you build your initial, conceptual class model you may (quite rightly) not yet have decided what the navigability should be. UML suggests different conventions; for example, the absence of an arrow may mean non-navigability, or may mean that navigability is unspecified. In this book, if a class diagram shows any navigability arrow you can assume that all such arrows are shown; if it does not, we are not specifying navigability.
UML now explicitly gives different presentation options.
81 l-2 and l-3 or -> xor UML's change
82 fig 6.11 and caption or -> xor UML's change
84 Fig 6.12 Delete empty compartment in "is taking" UML now specifies that empty compartments are omitted...
85 Fig 6.13 ... so I should have deleted it here too! Argh. Will report this for next printing...
85 - 86Points 1 up to Panel 6.2Replace with:
  1. Interface. An interface specifies a list of operations which anything matching the interface must provide. There are no implementations associated with any of the operations. An interface does not specify anything about the state of an object that matches it; so it has no attributes, and no association can be navigable from an interface. We'll discuss interfaces in more depth in the next subsection.
  2. <<type>>. A class which has the stereotype << type >> is like an interface except that it can have state, e.g. specify attributes as well as operations. It does not define any implementation.
  3. << implementation class >>. A class which has the stereotype << implementation class >> defines the physical implementation of its operations and attributes. It can realize a type.
Any object has exactly one implementation class, though it can have several types and match several interfaces. Usually we work with unstereotyped classes, but sometimes the extra precision given by the stereotypes is useful.
UML clarified the terms, and a little more details seems useful.
86 Panel 6.2 <<uses>> ->   <<use>> ; delete final bracketed sentence. UML has regularised the situation.
87 Point 2 kind of arrow -> realization arrow
87 l-3 <<uses>> ->   <<use>> see above
88 first Technical UML Note Delete. UML has regularised the situation.
88 second Technical UML Note Replace final sentence with
The notation is the same as we've described: for example, you could attach a lollipop to a use case symbol. The interface definition itself is always shown as a rectangle.
UML clarification.
89 Delete the technical UML note.
In l2 replace "stereotype << abstract >>" with "property {abstract}".
Add a new Panel 6.3:
We've just seen an example of a property being added to an element in a diagram to give more information about it. This is a powerful mechanism in UML, and is the other main way, apart from stereotyping, in which UML is made extensible.

Just as objects have values for their attributes, model elements, such as classes, have values for their properties. Properties are essentially to do with the model rather than the implemented system. For example, in a UML model every class has a Boolean property isAbstract, which is intended to have value true if the class is abstract and false otherwise. There's no suggestion that there should be an actual attribute isAbstract anywhere in the system: the property just provides a systematic way for a designer to record the design decision that this is an abstract class.

Different kinds of UML model elements have different properties available for recording appropriate decisions. Another particularly useful one is the isQuery property of operations. If a developer specifies that an operation has its isQuery property set to true, this records the design decision that invoking the operation should not affect the state of the system in any way. Such operations can be used whenever it's convenient in the model and as many times as you like, without fear of causing unwanted side-effects. For example, they can be used in conditions or constraints without causing confusion.

Any property can be written on a diagram by adding a label {propertyName = value} near the name of the element to which the property applies. Because so many properties are Boolean-valued with names isSomething}, UML provides a short form for those. We could write in full {isAbstract = true}, but we can instead write just {abstract}. Notice the similarity to how we write constraints: in both cases, the expression is written in curly brackets near the element name. You could think of a property as a kind of constraint.

The predefined properties of each kind of model element are described in the UML Semantics document. You can also define your own tagged values. That is, for any element of your model you can define a name (a tag) which should be filled in with a value. For example, if you wanted to record who was to write the code for a class and who was to review it, you might define two tags author and reviewer to apply to each class. Your class diagram could record the information; for example, by inserting {author = ``Perdita Stevens'', reviewer = ``Stuart Anderson''} near the name of the class. Of course, this will only be really useful if you have both an agreed set of tags among the development team, and some tool support for managing and displaying the tags.

What is the difference between defining a new tagged value, and defining a new stereotype? Stereotyping is a more powerful, heavyweight option, which is especially useful when you want to make several specialisations to a kind of model element. Defining a tagged value is more lightweight mechanism, for when you just want to associate a little more data with an element.

I decided we should really include properties.
p89-92may need to add one to page number to get page number in new edition.
98 Section 7.3 Replace by:
Optionally, there can be a box around the use cases in a use case diagram, labeled with the name of the system. The box represents the system boundary. An example is shown in Figure 7.4.

This can be useful when modeling a complex system which is split into different subsystems: you could have one use case diagram for each subsystem, in which case the system boundary may help to make it immediately clear which subsystem is being modeled. When drawing a use case diagram to represent a simple system, though, it is common to omit the box, and we shall do so in the rest of this book.

UML did the right thing and made the box optional at last!
104-112 This is the main change to UML. Here are updated versions of the diagrams in Chapter 8 Throughout:
  • <<uses>> -> <<include>>
  • <<extends>> -> <<extend>>
  • Replace the generalization arrows between use cases by dependency arrows (- - - - > )
105l9Add "If the target use case changes to contain different scenarios, the source use case will be affected because its longer scenarios will change too; but the target use case does not depend on the source use case. " explaining how this is - correctly! - now a dependency, and which way it goes
109-1108.2The Warning box that was before Section 8.2 has been deleted. Section 8.2 is renamed "Generalizations". Its new text is:
Both actors and use cases can be related by generalization, just as two classes can be. (footnote: Classes, Actors and UseCases are all Classifiers in UML and any Classifier can be generalized.) For example, in the library example, every human JournalBorrower is a BookBorrower, because the people entitled to borrow journals are also allowed to borrow books. We may choose to record a generalization relationship between the corresponding actors using the same notation that is used for classes, as shown in Figure 8.2.

When use cases are related by generalization the idea is to show a task and a specialized version of it. Again, we use the standard generalization arrow, which goes from the specialized use case to the more general use case. For example, if we have a use case Reserve book, we might have a specialization of it called Reserve book by telephone. This might be useful if the library system needed to behave differently for a telephone reservation; for example, if it means that the user's library card number has to be entered manually since the card cannot be scanned. This is very similar to extend and it is arguable that UML should not have both. A rule of thumb is that if you want to describe extra behaviour which should sometimes be added depending on ``run-time'' conditions, you probably want <<extend>>, whereas if you want a label for a specialized version of a whole task, you probably want generalization.

Generalization of use cases -- and of various other things! -- is a real can of worms in UML at present but it had to be mentioned...
115Technical UML Note Replace with:
We are choosing to avoid one of the more complex aspects of UML. When we draw a diagram involving an object theLibraryMember, we don't really have any particular object in mind: for example, we don't care what the library member's name is. We could equally well be representing Kent Beck borrowing Formal Methods for Fun, or Amir Pnueli borrowing Prototyping for Managers. That is, many different actual objects could play the role of theLibraryMember. It is possible to make this idea precise by explicitly describing the different roles that objects of a given class can play. UML allows interaction diagrams to involve objects, roles, or both. However, for most purposes it is clearer and simpler to use objects which are informally representative, so this is what we will continue to do. Technically, our diagrams are at the instance level, not the specification level, and we do not use explicit roles.
Frankly, UML's new treatment of roles is rather horrible, and I sincerely hope it will change! For now, I simply avoid teaching it in detail.
1259.4.5 Get the updated version of Figure 9.9 and replace from the second paragraph of section 9.4.5 to DQ72 with:
UML allows times and timing constraints to be represented on sequence diagrams in two ways. First, and most intuitively, you can let distances on the lifelines represent intervals of real time, either exactly or loosely, so that the vertical distance between two messages indicates the elapsed time between the messages. This tends to be inconvenient in practice as a way of getting more than an intuitive understanding of the relative timings of events, though you could experiment with drawing the diagrams on graph paper! More usefully, you can write timing constraints in terms of names for the arrows on your diagram. (footnote: UML's treatment of timing has recently changed, and is slightly inconsistent in version 1.3: we give one sensible interpretation.) You can use the message selector as the name if there is one and it's unambiguous: for example, in Figure 9.9 borrowed is used as the name of message 2.1. Alternatively you can give the arrow its own name, and show this by a ``timing label'' on the same level in the diagram. In Figure 9.9 we give the names A and C to the initial message and the return from it. Then in the simplest case, you just use the name to represent the time when whatever the arrow represents happens. For example, if the time between two consecutive messages being sent must be no more than 5 microseconds, we can add the labels A and B in the margin of the diagram level with the message arrows. Then we can record in the margin the constraint {B - A < 5 microsec}.

A further refinement is to consider the time taken for messages to pass between objects. So far we have drawn message arrows horizontally, which intuitively suggests that the message takes (virtually) no time to arrive. If the time taken for a message to arrive is significant as a fraction of the time for the whole interaction, it may be clearer to show the message arrow slanting downwards. If an arrow is named A and you write A as a time in a timing constraint, then strictly speaking you are referring to the time at the tail of the arrow (for example, the time when the message is sent: indeed, you can write A.sendTime() if you prefer). You can write the time at the head of the arrow, for example the time when the message is received, as A' (or A.receiveTime()). Figure 9.9 illustrates the notation, showing that the book borrower is not supposed to have to wait more than 5 seconds for confirmation that s/he can borrow a book (and the unrealistic suggestion that message 2.1 might take a significant time to arrive, but with the constraint that it should not take more than 1 second).

UML's treatment of timing has changed
134Point 2, l1 Delete "start a new thread of execution. That is, it can" This is at least misleading and arguably wrong.
135Fig 10.5, bottom line The half-head on the asynchronous arrow should point up, not down.
141l6After "is in." add " In fact, the state of the object also depends, in principle, on the objects it is linked to and their attributes and so on... However, systems in which two objects with the same attribute values could be in different states of a state diagram tend to be hard to understand and maintain." While it's a sensible design goal that the object's state depends only on its attributes, we should make clear that this isn't so (for the standard UML idea of attribute, which doesn't include object pointers etc. implementing links)
152l-10 and Fig 12.2 do/activeDetail -> include/activeDetail UML change.
154 Fig 12.4(b) Add horizontal dotted line across the outer state, as in (a). UML clarification(?)
156Warning, l-4(b) Delete from ",although" to the end of the para UML removed this definition.
160Fig 13.3, l4,5 of main text(b) Delete name "ether C" from diagram; delete "a name and"; delete "and what this particular link is known as". Strictly speaking, links in UML don't have names (associations do: but links are instances of associations). Not really sure about this, actually...
Chapter 14This is the other main set of changes to UML. Note the new diagrams 14.2 and 14.3, and:
163Replace from "A package" down to 14.1.1 with:
A package is shown on a diagram (any sort of diagram) as a rectangle with a `tab' on its top edge. The elements contained by a package can be drawn inside the package symbol, but need not be. They usually aren't, since the amount of detail required to show all the contents of a package usually makes this inconvenient: indeed the main purpose of using a package is normally to be able to hide this detail. Instead, the interior of a package is usually drawn in a separate diagram. In a CASE tool this diagram might be hyper-linked to the package icon. It's convenient to write the name of the package on the tab if its contents are shown, and in the body of the package symbol otherwise. Figure 14.1 illustrates all this notation.

You can use package symbols in all kinds of diagrams. You can show dependencies, associations and other relationships between packages when you want to show that some elements in the packages take part in the relationship, but prefer to abstract away the information about exactly which elements are involved.

Packages can contain almost any model elements that you wish to group together. As Figure 14.1 shows, a package can even contain another package. The hierarchical view of a system that results can be useful in large systems. As an alternative to showing the hierarchy by including one package symbol in another, you can use a tree structure; see Figure 14.2.

TECHNICAL UML NOTE: However, an ordinary package cannot take part in an interaction, because it is not a Classifier: for example, there is no notion of a plain package having instances or understanding messages. When we showed a package representing a subcollaboration in Chapter 11, we were using the convenient, but purely notational, UML rule that you can draw relationships to a package when what you mean is that some element in the package takes part in the relationship. An alternative would have been to model the subcollaboration as a subsystem, which as we shall see is a special kind of package which is also a Classifier.

163l-8 Add "For example, a more precise name for the class A shown in Figure 14.1 is P::A, and a more precise name for class C is P::R::C."
164 Replace from "Importing a package" to the end of the page with:
Importing or accessing a package
Every model element is in at most one (footnote: usually exactly one, but some model elements, e.g., operations, are not technically in any UML name space(!)) (most specific) namespace. In general, an element can name (know about) elements which are in its own package, and elements which are in surrounding packages. It can't, however, name elements from packages which don't contain its own. To see what this means, consider what the possible choices are for the class of attribute foo of class A in Figure 14.1. It would be legal for the attribute to have class B, because A and B are in the same package. D is also a legal choice, because D is in a package which contains A's package (there is always an implicit top level package, which in this case contains packages P and Q and class D). C is not a legal choice in UML, and neither is E, because these classes are not available in the namespace of A. To sum up:

Things outside a package can't see in.

If some element inside P needs to name something in a package (call it Q) that doesn't contain P, P must import or access Q, to make its elements visible inside P. For example, if we chose to make attribute foo have class E, we would have to add a dependency arrow (---->) from P to Q with stereotype <<import>> or <<access>>. The difference between importing and accessing a package is in the way its elements can be referred to. If P imports package Q, elements of P can refer to elements of Q just as if they were in package P; for example, the class of attribute foo could be given just as E. If P only accesses Q, P's elements must specify the package name as well as the element name. For example, the class of foo would be given as Q::E.

This may seem tedious, but it's a useful way to control dependencies. To name a thing is always to be dependent on it -- if the name of a thing changes, everywhere that names it has to change -- and if one part of a system is dependent on another we would like that to be explicit, so that changes in one place don't cause unexpected problems elsewhere. Package importing and accessing lets us record the high-level dependencies of parts of a system on one another, without getting overwhelmed by the detail of exactly what in one package depends on exactly what in another. It also allows us to do this without specifying the behavior of a package, if we wish: this is one reason why we sometimes want to use packages instead of subsystems, which we will consider below.

Q: What packaging and namespace mechanisms are there in programming languages you know? How does the namespace control at the programming language level compare with the namespace control in UML? How do you implement an <<import>> dependency between packages? What about <<access>>?}

Note: visibility is the other way round from what it was in originally.
1651.4.2 end of first para Add "or alternatively with a "fork" symbol near its name; see Figure 14.3"
1651.4.2 end of second para Get the new figure 14.3 and add:
All this information can be shown inside the subsystem symbol in a variety of ways: as you can imagine, the diagram gets complicated fast, and you are unlikely to use the notation unless you have a CASE tool which supports it. Figure 14.3 shows a simple example, in which there are two classes, Class1 providing the implementation of the subsystem's operation foo, and Class2 which collaborates with Class1 to provide another, perhaps more complex, piece of subsystem behaviour specified in use case Bar. The dotted ellipse ACollaboration} is shorthand notation for a collaboration which is fully described in a collaboration diagram elsewhere; we'll discuss this notation further in Chapter 18.
195Fig 17.2<<uses>> ->   <<use>>see above
196Fig 17.3use case relationship notation changes; see above
202Fig 17.5do/activeDetail -> include/activeDetail UML change.
204, 205, 209Fig 17.6, 17.7, 19.9, 17.10Delete carets see above