Just Typical: UML Stereotypes and Class Archetypes
Welcome to the third article in a series introducing UML and object modeling from a Java programmer's perspective. In the previous articles, we introduced UML class diagrams comparing the way classes and relationships between classes are represented in the Unified Modeling Language (UML) and the Java programming language. In those articles, we started with Java source code and looked at how that could be represented graphically using the UML. In this article, we start from the opposite end and look at the effect a UML mechanism has on the way we work with our code.
Extending UML with Stereotypes
UML has a number of mechanisms that can be used to extend its core concepts. Probably the most widely known are stereotypes. UML stereotypes can be used to further define an element in a UML diagram. By default, stereotypes are depicted as a keyword surrounded by guillemot characters, the quote marks used in several European languages. Because guillemots look like two angle brackets, this is an accepted alternative representation for those of us who do not have ready access to European characters on our keyboards or who use more traditional computer systems.
Stereotypes can be applied to almost anything in the UML, including classes, attributes, operations, and associations in class diagrams. For example, we can use stereotypes to show a categorization of classes in our diagrams. Figure 1 shows stereotypes being used to indicate the role played by a class in a version of the popular state pattern adapted from the Design Patterns book by Gamma, et al1. UML defines a large number of standard stereotypes2, and we can use these or define our own, as shown in Figure 1.
Figure 1 UML stereotypes used to show the role of a class in a design pattern.
Notational Note
The MessageStatus interface in Figure 1 should officially have the word interface within guillemots or pairs of angled brackets. However, the implementers of the Together ControlCenter3 product used to produce the figure decided to leave them out to distinguish interfaces from other stereotypes because unlike other stereotypes, "Interface is a peer of Class within the UML metamodel (both are Classifiers)."2
Historical Note
Until UML 1.4 (September 2001), a diagram element in the UML could have only a single stereotype. With UML 1.4, the Object Management Group lifted this restriction, and a diagram element may now have multiple stereotypes. Many UML modeling tools have yet to catch up and do not yet offer this particular feature.
This is all very well, and stereotypes are obviously useful in clarifying the use of something in a diagram, but how does that affect our Java source code? At one level, the answer is "not at all;" there is nothing in Java that enables us to categorize classes in this way (inheritance and interfaces were discussed in the previous article and have their own special representations in UML). However, at another level, we can start to use conventions to further communicate the meaning of our source code clearly and concisely. By agreeing on the meaning of a stereotype, we can include that stereotype as a new javadoc tag in our source code comments and reduce the amount of textual comment we need to write to communicate the purpose of our class. Tools that can be taught to recognize those tags can help generate or verify code that does indeed conform to the agreed convention. The following source code shows the skeleton of the Sent class from Figure 1 with the stereotype added as a custom javadoc tag.
/** * @stereotype concreteState * @author Steve Palmer * @version 0.0001 */ public class Sent implements MessageStatus { }
Classes are not the only things in the UML that can be given stereotypes to constrain their definition. Figure 2 shows a dependency relationship between two classes using a stereotype to indicate the type of dependency; in this case, objects of the Factory class are responsible for creating objects of the Item class. The source code that follows Figure 2 shows one possible custom javadoc tag that could be used to describe this dependency clearly and concisely.
Notational Note
We have seen three different kinds of relationship drawn between classes in the previous articles. This is the fourth. Associations are drawn with a solid line and an open arrowhead if the relationship is traversable in only one direction. Generalizations are drawn with a solid line and a closed arrowhead from subclasses to the superclass. Realizations are drawn as dashed lines with a closed arrowhead from an implementation to an interface. Now, we have the fourth and final combination of arrowheads and line types: dependencies drawn as dashed lines with open arrowheads from the dependent class.
Figure 2 UML dependency relationship further defined by the instantiate stereotype.
public class Factory { /** * @dependency <<instantiate>> Item * @return a new Item */ public Item createItem() { return new Item(); } }
Operations and attributes can also be given stereotypes. Figure 3 shows a class with two operations stereotyped to indicate whether or not they modify the values of the attributes of their objects. The source code that follows shows again the use of a custom javadoc tag to communicate the stereotype.
Figure 3 Operations with UML stereotypes.
public class Sale { ... /** * @stereotype query * @return total price of sale */ public BigDecimal calcTotal() { } ... /** * @stereotype update * @param price the cost of a single unit of the product being sold */ public void setPricePerUnit(BigDecimal price) { this.price = price; } ... }
The reward for doing the extra work of adding the custom javadoc tags to our code is not only less comment text to write, but the opportunity for tools to process those tags and do the following:
Regenerate more complete UML diagrams from our source code than otherwise possible.
Generate additional information in Javadoc style output.
My favorite modeling tool, TogetherSoft's Together ControlCentre3, uses exactly this sort of approach to store all the extra semantic information from a UML class diagram that cannot be expressed directly in Java source code. However, more modest tools can quite easily be created using Javadoc doclets or any other text file processing engine.
Shape Shifters
At the beginning of the article, we said that angle brackets and guillemots were the default way of showing a stereotype. Stereotypes can also be shown by a change of graphic symbol or shape. Figure 4 shows an example of two classes with the <<actor>> stereotype. The Cashier class is drawn using the alternative symbol for the <<actor>> stereotype, and the Manager class is drawn using the default representation. With the alternative symbol, it is not easy to list the attribute and operations so they are normally omitted from the diagram. A third representation that places a small version of the alternative symbol to the right of the class name in the usual rectangle symbol is also allowed and is becoming increasingly popular in recent times.
Figure 4 An alternative icon for the actor stereotype next to the default representation.
There is one big disadvantage of using the alternative graphical symbol approach when drawing class diagrams. If some people are unfamiliar with the symbols being used, it can become much harder to understand what is going on. Also, additional symbols add to the burden of learning to read the diagrams. In these articles, we have deliberately concentrated on the subset of UML class diagram notation most frequently used. There is more than enough additional notation in the UML class diagram standard without adding a vast number of custom shapes and symbols. Fortunately, the UML standard2 does rather begrudgingly allow us an alternative.
In Glorious Color
Instead of changing the shape of a symbol when it's given a certain stereotype, we can change the color or the texture of the diagram element. Using color means that we can retain the usual graphical shapes and symbols, while adding the same (if not more) visual impact that the use of different shapes gives. Also, unlike a set of abstract shapes, a simple color-coding scheme is very easily learned by both developers and client representatives.
Figure 5 Modeling in color.
Figure 5 shows a color-coded class diagram using Peter Coad et al's4 four class archetype categorization to further define classes.
The pink <<moment-interval>> classes represent events or activities that we need to keep track of for business or legal reasons in our systems. Examples of pink classes are CarSale and CarRental.
The yellow <<role>> classes represent a way of participating in an event or activity by a green entity class. Examples of yellow classes are CarSalesperson and Customer.
Green entity classes are further categorized into <<party>> (usually a person or organization), <<place>> (the location where the event or activity occurs), and <thing>> (the real-world objects involved in the event or activity).
The fourth archetype is the blue catalog-entry-like-description (<<description>> for short), and represents the difference between something like a physical car on someone's drive and a description of the model of that car in the showroom catalog. The car model is the blue class, and it contains a number of values and ranges of values that hold for all cars of that model; each physical car is represented by a green <<thing>> class.
Classes belonging to a particular class archetype have more or less the same sort of attributes and operations. Classes of particular archetypes also tend to interact with classes of other archetypes in generally predictable ways. These patterns of characteristics and behavior can help us very rapidly build robust and extensible object models, quickly identify attributes and operations that we might otherwise miss, and give us increased confidence in the structure of our code. Figure 5 shows the sorts of attributes and operations we might find in classes of each archetype, and also the most typical way in which the archetypes tend to relate to each other.
Historical Note
The more or less nature of the patterns communicated by class archetypes eventually resulted in the use of the term archetype instead of the tighter patterns typically associated with the English word stereotype. The confusing use of UML stereotypes to textually indicate the archetype of a class and the appropriateness of each of those terms are topics best discussed over beer and pizza when deadlines have been met.
To Color or Not to Color
The UML specification discourages the use of color because of the difficulty it causes color blind people and the problems of greyscale printers, copiers, and fax machines. However, continuing to display the stereotype in its usual textual form enables the most severely color-blind to participate; and with an appropriate choice of primary colors, keeps the diagrams readable when greyscaled by color-challenged devices, as shown in Figure 6.
Figure 6 A grayscaled color-coded diagram
When working informally, I use four pads of different colored, three-inch square Post-itTM notes to represent classes on flipchart pads drawing associations with a suitable marker pen.
In the same way that after you have watched color television or seen color photographs, you do not want to return to black and white except for nostalgic reasons, most people never want to return to the shallowness of the black-and-white version once they have experienced object modeling in color.