About UML
UML is a standard maintained by the Object Management Group. UML has its own terminology that is independent of implementation languages such as Java and C#. UML calls pieces of information stored in instances of a class attributes rather than variables. UML calls a class’s encapsulations of behavior operations, rather than functions, procedures, methods, or subroutines.
.NET’s concept of properties do not directly match anything in UML. If a class has a property named Color, you would draw it in a UML diagram with operations named GetColor and SetColor.
Classes
UML uses a few different kinds of diagrams. This article will focus on class diagrams. A class diagram is a diagram that shows classes, interfaces, objects, and their relationships. The most basic element of a class diagram is a class. Figure 1 shows many of the features that a class can have in a class diagram.
Figure 1: An Example of a Class
Classes are drawn as rectangles. The rectangles may be divided into two or three compartments. The class rectangle shown in Figure 1 has three compartments. The top compartment contains the class’s name. The middle compartment lists the class’s attributes. The bottom compartment lists the class’s operations.
The symbols that precede each attribute and operation are visibility indicators. The possible visibility indicators and their meanings are as follows:
Symbol | Name | Description |
---|---|---|
+ | Public | Unrestricted access |
# | Protected | Access only by the containing class or derived types (children) |
- | Private | Access restricted to the containing class |
UML does not have any simple way of indicating Friend variables or functions.
The attributes in the middle compartment are shown as the following:
visibilityIndicator name : type
Therefore, the two attributes shown in the class in Figure 1 are private. The name of the first attribute is instance and its type is KeyManager. The name of the second attribute is prevKey and its type is Key.
Although not shown in Figure 1, an initial value can be indicated for an attribute by following the attribute’s type with an equals sign and the value, like this:
shutDown:Boolean = false
The operations in the bottom compartment are shown as:
visibilityIndicator name ( formalParameters ) : returnType
The GetInstance operation shown in Figure 1 returns a KeyManager object. The synchKey operation shown in the class in Figure 1 does not return any result.
A formal parameter of an operation consists of a name and a type like this:
AddToken(token:String)
If an operation has multiple parameters, commas separate them:
DisplayTokenList (tokenList:ArrayList, separator:String)
Formal parameters may each be preceded by one of the words in, out, or inout like this:
GetInfo(inout status:StatusCode, out msg:string):Boolean
A UML formal parameter that is preceded by in or nothing has the value of its actual parameter passed into the operation. However, the operation cannot modify the actual parameter’s value. This is similar to a parameter of a Java method or a VB.NET parameter that is preceded by ByVal.
A UML formal parameter that is preceded by inout has the value of its actual parameter passed into the operation. Any changes that the operation makes to the value of its formal parameter cause the value of the actual parameter to be modified. This similar to a VB.NET parameter that is preceded by ByRef.
The usual way to implement this in Java is to make the value of a method’s parameter a single element array. The value of the array element is used as the parameter value. The method can change the value of the actual parameter by modifying the value of the array’s element.
public class Util { /** * Increment the argument and check for overflow. * * @param x * An array with a single element whose value is to be * incremented. * @return true unless the value of the element overflowed. */ public static boolean incrementCheckingOverflow(short[] x) { short i = x[0]; x[0] = (short)(i + 1); return i > 0 && x[0] < 0; } }
A UML formal parameter that is preceded by out is used only to pass a value out of the operation.
The operations shown in the class in Figure 1 are preceded by a word in guillemets (double angle brackets), like this:
«constructor»
In a UML drawing, a word in guillemets is called a stereotype. A stereotype is used like an adjective to modify what comes after it. Some stereotypes have predefined meanings. The «constructor» stereotype indicates that the operations following it are constructors. The «misc» stereotype indicates that the operations following it are regular operations.
One last element that appears in Figure 1 is an ellipsis (…). If an ellipsis appears in the bottom compartment of a class, the class has additional operations that the diagram does not show. If an ellipsis appears in the middle compartment of a class, it means that the class has additional variables that the diagram does not show.
Often, it is not necessary or helpful to show as many details of a class as were shown in the preceding class in Figure 1. We may choose to omit details because we have not decided them yet or because they seem extraneous. As is shown in Figure 2, a class may be drawn with only two compartments.
Figure 2: A Two Compartment Class
It is common in UML diagrams not to include all possible details. The usual reason for leaving a detail out of a diagram is either that the detail is not relevant or that the detail has not yet been decided. UML syntax allows most details of a class, other than its name, to be omitted.
When a class is drawn with only two compartments, as shown in Figure 2, its top compartment contains the class’s name and its bottom compartment shows the class’s operations. Leaving out the compartment that contains the attributes just means that the class’s attributes are not shown. It does not mean that the class has no attributes.
Visibility indicators may be omitted. When an operation or attribute is shown without a visibility indicator, it means there is no indication of the operation’s or attribute’s visibility. It does not imply that they are public, protected, or private.
An operation’s parameters may be omitted if its return values also are omitted. Omitting an operation’s parameters is common in a high-level design that just identifies operations. In Figure 3, for example, the return values and parameters are omitted from the class.
Figure 3: A Simplified Class
The simplest form of a class has just one compartment that contains the class name, as shown in Figure 4.
Figure 4: One Compartment Class
A one-compartment representation of a class merely identifies the class. It provides no indication about what operations or attributes the class has.
Interfaces are drawn in a manner similar to classes. The difference is that the name in the top compartment is preceded by an «interface» stereotype, as shown in Figure 5.
Figure 5: An Example of an Interface
A .NET delegate can be similarly indicated by using a «delegate» stereotype and showing exactly one operation.
Generic classes and interfaces are indicated by an additional box with a dashed border in the upper right corner of the class or interface. The dashed box contains the names of the type parameters that can be specified for the class or interface. Figure 6 shows an example of this:
Figure 6: Generic Interface
What is shown in Figure 6 is actually a family of interfaces that work with different types that are specified through a parameter. Classes or interfaces that belong to such a generic family and work with specific types are named by specifying the generic class or interface followed by its parameters specified in angle brackets like this:
IEnumerator<Product>
Class Diagrams
Classes and interfaces are important elements of class diagrams. Other elements of a class diagram show relationships between classes and interfaces. Figure 7 is a typical class diagram.
Figure 7: Class Diagram
The lines in Figure 7 indicate the relationships between the classes and an interface. A solid line with a closed hollow head such as the one in Figure 8 indicates the relationship of a subclass that inherits from a base class.
Figure 8: Inherits From Arrow
The class diagram in Figure 7 shows the abstract (MustInherit in VB.NET terminology) class Product as the base class of the ConcreteProduct class. You can tell that it is abstract because its name is italicized. You can tell that its functions and subroutines are abstract because they are also italicized.
A similar sort of line is used to indicate that a class implements an interface. It is a dotted or dashed line with a closed head, like the one in Figure 9.
Figure 9: Implements Interface Arrow
The class diagram in Figure 7 shows that the Factory class implements the IFactory interface.
The other lines in Figure 7 show other types of relationships between the classes and interface. UML calls these other types of relationships associations. A number of things can appear with associations that provide information about the nature of an association. The following items are optional, but they should be used wherever they make the nature of the relationship clearer.
- Association name: Somewhere around the middle of an association line there may be an association name. The name of an association should be capitalized. There may be a triangle that looks like an arrow head at one end of the association name. The triangle indicates the direction in which you should read the association. Looking at Figure 7, you see that the association between the Factory and ConcreteProduct classes has the name Creates.
- Navigation arrows: Arrowheads that may appear at the ends of an association line are called navigation arrows. Navigation arrows indicate the direction in which you may navigate an association.
Looking at the association named Creates in Figure 7, you see a navigation arrow pointing from the Factory class to the ConcreteProduct class. Because of the nature of creation, it seems clear that the Factory class is responsible for creating instances of the ConcreteProduct class.
The nature of some associations is less obvious. To make the nature of such associations clear, it may be necessary to supply additionalinformation about the association. A common way to clarify the nature of an association is to name the role that each class plays in the association.
- Role Name: To clarify the nature of an association, the name of the role each class plays in the association can appear at each end of an association, next to the corresponding class. Role names should be lower-case. This makes them easier to distinguish from association names, which should becapitalized.
In Figure 7, the CreationRequestor class and the IFactory interface participate in an association named Requests-Creation. The CreationRequestor class participates in that association in a role named requestor. The IFactory interface participates in that association in a role named creator.
- Multiplicity Indicator: Another helpful detail of an association is how many instances of each class participate in an occurrence of the association. A multiplicity indicator may appear at each end of an association to provide this information. A multiplicity indicator can be a simple number like 0 or 1. It can be a range of numbers indicated like this:
0..2
An asterisk as the high value of a range means an unlimited number of occurrences. The multiplicity indicator 1..* means at least one instance; 0..* means any number of instances. A simple * is equivalent to
0..*
Looking at the multiplicity indicators in Figure 7, you will see that each one of the associations in the drawing is a one-to-many relationship. Figure 10 is a class diagram that shows a class with multiple subclasses.
Figure 10: Individual Inheritance Arrows
Although the drawing in Figure 10 is perfectly valid, the UML allows a more aesthetically pleasing way to draw a class with multiple subclasses. You can combine the arrowheads, as shown in Figure 11. The diagram in Figure 11 is identical in meaning to the diagram in Figure 10.
Figure 11: Combined Inheritance Arrow
Sometimes, there is a need to convey more structure than is implied by a simple one-to-many relationship. You may want to convey the idea that one object contains a collection of other objects. This kind of relationship is called an aggregation. A hollow diamond at the end of the association indicates aggregation. The hollow diamond appears at the end of the association attached to the class that contains instances of the other class. The class diagram in Figure 12 shows an aggregation.
Figure 12: Aggregation
The class diagram in Figure 12 shows a class named MessageManager. Each of its instances contains zero or more instances of a class named MIMEMsg.
UML has another notation to indicate an even more structured relationship than aggregation. This relationship is called composite aggregation. For an aggregation to be composite, two conditions must be satisfied:
- Aggregated instances must belong to only one composite at a time.
- Some operations must propagate from the composite to its aggregated instances. For example, when a composite object is cloned, its Clone function will typically clone the aggregated instances so that the cloned composite will own clones of the original aggregated instances.
Figure 13: Composite Aggregation
Figure 13 is a class diagram that contains a composite aggregation. The class diagram shows a Document class. Document objects can contain Paragraph objects. Paragraph objects can contain DocChar objects. Because of the composite aggregation, you know that Paragraph objects do not share DocChar objects and Document objects do not share Paragraph objects. Because the classes involved in a composite aggregation propagate operations to each other, they generally implement a common interface or extend a common superclass.
Some associations are indirect. Instead of classes being directly associated with each other, they are associated indirectly through a third class. Consider the class diagram in Figure 14. The association in Figure 14 shows that instances of the Cache class refer to instances of the Object class through an instance of the ObjectID class.
Figure 14: Association Class
An association between classes or interfaces implies a dependency that involves an object reference connecting two objects. Other types of dependencies are possible. A dashed line with an open arrowhead is used to indicate a dependency in the more general sense. Figure 15 shows an example of such a dependency.
Figure 15: Dependency
The classes in a class diagram can be organized into packages. Packages are drawn as a large rectangle with a small rectangle above the large rectangle. The small rectangle contains the name of the package. The small and large rectangles are arranged to have an overall shape similar to a manila folder. The class diagram in Figure 16 contains a package named ServicePackage. A visibility indicator can precede the name of classes and interfaces that appear within a package. Public classes are accessible to classes outside of the package; private classes are not.
Figure 16: Package
Objects
Class diagrams can include objects. Often, objects are drawn as shown in Figure 17. The object shown in this figure is an instance of a class named Area. The underline tells you that it is an object. A name may appear to the left of the colon (:). The only significance of the name is that it you can use it to identify the individual object.
Figure 17: Object
The lines that connect two objects are not associations. The lines that connect objects are called links. Links are run time connections between objects, whereas associations are relationships between classes. A link is an occurrence of an association, just as an object is an instance of a class. Links can have association names, navigation arrows, and most of the other embellishments that associations can have. However, because a link is a connection between two objects, links may not have multiplicity indicators or aggregation diamonds.
Some diagrams consist just of objects and links. Such diagrams are considered a kind of class diagram. However, there is a special name for this kind of diagram. A diagram that consists of just objects and links is called an object diagram. Figure 18 is an example of an object diagram.
Figure 18: An Object Diagram
Summary
This article has shown you how to use UML to describe classes, interfaces, objects, and the relationships among them. The next article will show you how to use UML to refine a class or object model.
About the Author
Mark Grand is a consultant and book author with over 30 years of experience who specializes in Distributed Systems, Object-Oriented Design, and Java. He was the architect of the first commercial B2B e-commerce product for the Internet.
Mark is most widely known for his best selling design pattern books. Mark has taught for U.C. Berkeley, Sun, and other organizations. Mark is based in the Atlanta area. He has been involved with object-oriented programming and design since 1982. |