In this section, we show two small examples of applying MDA. The examples themselves are not very complex, even rather trivial. These examples do not show the advantages of MDA. The purpose is to show how the MDA framework is applied in some concrete examples. In both examples we take a look at a high-level PIM modeled in UML and a lower-level PSM for Java, also written in UML. Chapter 4 gives a more complex and realistic example.
2.5.1 Public and Private Attributes
In the first example we define a transformation between two UML models. The source model is a platform independent model, which is transformed into a lower level, more platform specific model for use with Java. The focus is on transforming public attributes into their respective get- and set-operations. One of the classes in the PIM is shown in Figure 2-8. The class Customer contains three attributes: title, name , and dateOfBirth . All attributes are declared public. In a high-level PIM it is normal to use public attributes. The meaning of a public attribute in a PIM is that the object has the specified property, and that this property can change value over time.
Figure 2-8. Platform independent model
In the PSM, where we model the source code instead of the business concepts, the use of public attributes is considered to be bad design. It is better to apply information hiding techniques and encapsulate the public attributes as shown in Figure 2-9. All attributes are private and all access to the Customer is directed through well-defined operations. This allows the customer object to have control over its use and over its change of attributes.
Figure 2-9. Platform specific model targeted at Java
Both PIM and PSM are useful, as they provide the right level of information to different types of developers and other stakeholders in the software development process. However, there is a clear relationship between the models. The transformation definition to transform the PIM into the PSM has several rules. The transformation rules are:
This transformation rule has a reverse, a rule that transforms an aspect of the PSM into a PIM, which is formulated in the other direction:
Because in this example we know that the targeted programming language is Java, we can write another transformation definition that transforms the PSM into source code. Combining and automating both transformations generates source code for the necessary operations, derived completely from the PIM.
We can extend the example above with more classes and associations between those classes. In Figure 2-10 the PIM is extended with two classes: Order and Item . The model shows that a customer may have multiple orders and each order may have one or more items. In the PSM, next to transforming the public attributes, we need to replace the associations by something that is directly mappable to the programming language. Naturally, for mapping associations with a multiplicity greater than one, we make use of the Java collection classes. The extra transformation rules are:
Figure 2-10. Platform independent model, extended
The transformation that combines both the rules for public attributes and the rules for associations results in the PSM shown in Figure 2-11.
Figure 2-11. Platform specific model, extended
Looking at the PSM we see that the difference with the PIM is larger than in the first example. The associations between the classes are hard to find. If we only have the PSM at our disposal, we can deduce that Order has an association with Customer , because of the customer field. The multiplicity of the association must be zero or one. We cannot find whether this association is directed or not. The association between Order and Item is completely lost because in Java there is no restriction on the type of the elements that can be in the set items in Order, and Item does not contain any reference to Order . Defining a reverse transformation for the association transformation definition is basically impossible .
Note that in the transformation rule design decisions are written down. In the above rule we have chosen to have set operations for Set -type attributes that need a Set as parameter. This has resulted in the setOrders(o : Set) operation of Customer. An alternative would be to only have an addOrder(o : Order) operation. This makes addition of single orders easier. These choices are made by the person (or tool vendor) that specifies the transformation.
Often one would want to have explicit control over the transformation, e.g., stating that a certain association needs to be transformed to an attribute of type HashSet instead of Set , or that a certain association needs both operations setOrders() and addOrder() . We call this tuning of the transformation. Section 7.2 gives more information on this subject.