To effectively use the Unified Modeling Language (UML) when developing Java applications, developers must have a thorough understanding of the UML elements and how these elements map to Java. For now, I’ll focus on one aspect of UML: the elements of a class diagram.
Arguably, class diagrams are the most often used UML diagrams. The purpose of a class diagram is to specify the structural makeup of the system. This includes class relationships and the attributes and behaviors associated with each class. Class diagrams are remarkable at illustrating inheritance and composite relationships. To use class diagrams as an effective communication tool, developers must have a consistent understanding of how the elements appearing on a class diagram are translated to Java. Let’s further explore this translation.
The following items represent the elements of a class diagram and their corresponding representation in Java. I will list the name of the element, followed by a short code snippet and a picture representing what that element would look like on a class diagram. A short description of the element will conclude each section.
A class (Figure A) is a blueprint for an object, containing three compartments. The first represents the name of the class as defined in Java. The second represents the attributes. The third compartment represents methods on the class.
Attributes and operations can be preceded with a visibility adornment. A plus sign (+) indicates public visibility. A minus sign (-) denotes private visibility. A pound sign (#) denotes protected visibility. Omission of this visibility adornment denotes package-level visibility. If an attribute or operation is underlined, this indicates that it is static. An operation may also list the parameters it accepts, as well as the return type, as seen in the Java section in Figure A.
Packages (Figure B) are general-purpose grouping mechanisms. A package in UML translates directly into a package in Java. In Java, a package can contain other packages, classes, or both. When modeling, you’ll typically have logical packages that serve primarily to organize your model. You’ll also have physical packages that translate directly into Java packages within your system. Packages have a name that uniquely identifies the package.
An interface (Figure C) is a collection of operations that specify a service of a class. This translates directly to an interface type in Java. An interface can be either represented by the above icon or by a regular class with a stereotype attachment of <<interface>>. Typically, an interface will be shown on a class diagram as having realization relationships with other classes.
The following examples illustrate the relationships in isolation based on the intent. Though syntactically correct, these samples below could be further refined to include additional semantic meaning within the domain with which they are associated.
A using relationship between entities implying a change in specification of one entity may affect the entities that are dependent upon it (Figure D). More concretely, this translates to any type of reference to a class or object that doesn’t exist at the instance scope. This includes a local variable, reference to an object obtained via a method call (as in the example below), or reference to a class’s static method where an instance of that class does not exist. A dependency is also used to represent the relationship between packages. Because a package contains classes, you can illustrate that various packages have relationships between them based upon the relationships between the classes within those packages.
A structural relationship between entities specifies that objects are connected. The arrow is optional and specifies navigability. No arrow implies bidirectional navigability. In Java, an association (Figure E) translates to an instance scope variable as in the example code in the Java section of Figure E. Additional adornments can also be attached to an association. Multiplicity adornments imply relationships between the instances. In the example code above, an Employee can have 0 or more TimeCard objects. However, a TimeCard belongs to a single Employee.
Aggregation (Figure F) is a form of association representing a whole/part relationship between two classes. Aggregation implies that the whole is at a conceptually higher level than the part, whereas an association implies both classes are at the same conceptual level. Aggregation also translates to an instance scope variable in Java.
The difference between association and aggregation is entirely conceptual and is focused strictly on semantics. An aggregation also implies that there are no cycles in the instance graph. In other words, it must be a unidirectional relationship.
Composition (Figure G) is a special form of aggregation, which implies lifetime responsibility of the part within the whole. Composition is also nonshared. So while the part doesn’t necessarily need to be destroyed when the whole is destroyed, the whole is responsible for either keeping alive or destroying the part. The part cannot be shared with other wholes. The whole, however, can transfer ownership to another object, which then assumes lifetime responsibility.
The relationship below between Employee and TimeCard might better be represented as a composition versus an association.
Generalization (Figure H) illustrates a relationship between a more general element and a more specific element. Generalization is the UML element to model inheritance. In Java, this directly translates into use of the extends keyword.
The realization (Figure I) relationship specifies a contract between two entities in which one entity defines a contract that another entity guarantees to carry out. When modeling Java applications, a realization translates directly into the use of the implements keyword.
As I’ve shown, the elements appearing on a UML class diagram have a very precise mapping to the Java programming language. Team members can take advantage of this precision to enhance communication pertaining to the structural makeup of the system.
Subscribe to the Developer Insider Newsletter
From the hottest programming languages to commentary on the Linux OS, get the developer and open source news and tips you need to know. Delivered Tuesdays and Thursdays