Class Diagrams

This is a quick introduction to using UML Classes Diagrams with an emphasis on JavaGen, Java and Poseidon 3.0.

JavaGen generates static or structural models which are primarily represented by Class Diagrams. The most important features of Class Diagrams and the Java-specific attributes they map to are:

There are a few more specialized UML features, but the ones listed above will get the job done 99% of the time.

Naming Identifiers

UML tools can be very lenient regarding the allowed naming of classes, attributes and operations, Java on the other hand has strict rules regarding identifier names. In general you should only use alphanumeric characters and the underline character (a-z A-Z 0-9 _), white space is not allowed. Be particularly careful with Poseidon and the tab key or you'll end up with invisible white space in your identifier names.

UML Packages

You should always organize your classes into package. In addition to the conceptual clarity, good partitioning can make it easy to package your deployment modules using build tools like Ant. Unlike Java, it is easy to refactor package organization in UML. In Poseidon for example, you just pick the names from a drop down list:

package naming example

UML Classes

Java programmers shouldn't have much trouble getting used to UML classes, accept for some terminology differences, they are very similar to Java classes. Here is a simple example class:

simple pojo class

UML Interfaces

The UML representation of interfaces is similar to UML Classes with an added <<interface>> stereotype.

As in Java, interfaces are primarily intended to express abstract behavior in the form of method signatures.

interface example

You can also declare constant values in an interface. You want the resulting Java fields to be marked static and final with the constant value assigned, for example:

public static final String VISA = "visa";

In Poseidon this is achieved by checking static and frozen and assigning the Initial Value as shown:

constant attribute example

Note that you must use proper Java syntax and surround the string constant with double quotes.

UML Attributes

UML attributes map to Java fields. JavaGen breaks attributes into two categories:

  • fields - low-level implementation variables largely ignored by the code generator
  • properties - semantically meaningful variables that trigger support code generation

Properties have getter and setter methods, are included in support methods such as toString, equals and hashCode and depending on the context my be endowed with other powers, such as persistence. Most of the time JavaGen can guess how to treat a attribute, for example if an attribute is static or transient JavaGen will treat it as a field. You can explicitly specify one or the other by using the <<field>> or <<property>> stereotypes.

explicit property and field example

UML Associations

UML associations are one of the most powerful abstractions in UML, a simple line between two classes can represent something that takes hundreds of lines of Java code to implement. JavaGen will happily write all this code for you including such details as deployment descriptors, database foreign key relationships and life-cycle management once you understand a few key concepts. The most important aspects of associations are:

  • Cardinality - a cardinality of one on a given relationship end generates a Java reference, for example
    public class Customer {
    	Purchase purchase;
      ...
    }
    A cardinality of many (depicted as a number or *) generates a Java container:
    public class Customer {
      List purchases;
      ...
    }
    To see how to generate a specific container type, see the specific module documentation.
  • Navigability - simply means weather given an instance of an object on one side of a association you can access an instance on the other side. If a association can only be traversed in one direction then this will be indicated with arrows. If there are no arrows then the association is bi-directional.
  • Association end - A given class only sees the association through the attributes set on the association end. In other words that simple line actually represents two independent sets of data, one for each of the two classes involved. Besides the cardinality and navigability the most important attribute is the association end name. This name is used to generate the getter and setter methods and in persistent classes database column names. We recommend using singular names for single cardinal associations and plural names for many ended associations.
  • Aggregation - This largely has to do with ownership and lifecycle issues. Composition associations such as
    composition example
    indicate a parent-child relationship between classes were the child object can not exists with out the parent. Translated to Java programs this means children are deleted when their parents are. Translated into relational databases, composition indicates cascading delete and update behavior.
    The aggregation association
    aggregation example
    has no implementation effects and exhibits the same behavior as a regular association.

Keeping track of which association end belongs to which class can be confusing. Remember a given class sees the association through the far end of the association. So for the one-to-many association between two classes Customer and Purchase

one to many example

you would place the cardinality (*) and name (purchases) on the Purchase end of the association.

association end dialog box

The resulting code found in the Customer class would be something like:

public class Customer {
  List getPurchases() {...}
  void setPurchases(List purchases) {...}
  ...
}

UML Operations

UML operations become Java methods. If a return type is specified, JavaGen will generate a default return statement so the code will compile. You can also paste in arbitrary source code into the method body.

UML Generalizations

Generalizations are just the way you indicate inheritance in UML:

generalization example

UML Realizations

A UML realization is just an implementation of an interface.

realization example

UML Dependencies

dependency example

A dependency indicates that one object is dependent on another. In the most basic case JavaGen will generate an import statement. However, based on the type of object at the other end, JavaGen can generate other supporting code needed to access the object. For example if the object is a EJB, JavaGen will generate the EJB home access code.

By attaching a specific stereotype to a dependency, JavaGen will perform model-to-model transformations like generating an interface or copying properties from one class to another (see Model-to-Model Transformations).