We've elegantly avoided one critical issue so far: How do we connect the marks to the model elements to which they may pertain?
In the remote/local example, the mark only applies to actions that read, write, or clear an attribute. In the UML metamodel, those actions are modeled as a supertype StructuralFeatureAction, and each attribute action can be local or remote. The result is that the mark AccessorType is somehow associated with StructuralFeatureAction.
After all this ranting about keeping the marks separate from models, it would be pathological now to pollute the metamodel with marking model concepts. Just as we viewed marks as lightweight, nonintrusive extensions added to the developer model, so too we view the marking model as a plastic sheet laid over the metamodel specifically, a plastic sheet with an extended attribute of StructuralFeatureAction called AccessorType, as shown in Figure 6-1.
Figure 6-1. A very simple marking model
This model is intended to convey that the AccessorType mark is associated with structural feature (attribute) actions in the source metamodel; each attribute action has a value for the mark. We do not intend to leave the impression that the metamodel should be extended directly. (There will be a question about it on the test!) Note that if we were to make the decision between local and remote access for classes as a whole, we would create the mark definition so that it applies to Class model elements instead.
A given model element can have several marks associated with it. For example, consider the transformation of a model into a design expressed in terms of objects that can be stateful or stateless, transient or persistent, local or remotely accessible, identifiable or not. In this case, multiple mapping rules are applicable to each source model element, so there can be marks that enumerate the choices for state, persistence, accessibility, and identity, respectively, to remove this ambiguity. Each of these marks is an extended attribute of the appropriate metamodel class.
The plastic sheet analogy suggests that some marks might be related and could all be placed on the same sheet. For example, a mark isPersistent could apply both to classes and attributes, with the implicit rule that any class that has a persistent attribute must also be so marked, so there is a home for the column in the generated table. A single sheet could contain multiple related marks, such as an additional string that describes the target of the persistent data, say database or backup. Removal of the plastic sheet, then, implies the removal of the entire concept of persistence from the system.
This idea implies that it's useful to consider the reusability of each marking model element: Elements that are likely to be used together by existing and future mapping functions should be grouped together in one marking model. The marks that capture these design decisions can be reused if the source model is transformed into another target model where comparable design decisions would have to be made.
A typical example of the usefulness of marking model grouping is a mapping function that spans multiple platforms. For this example, an ideal marking model partitioning uses two partitions: one for the platform-independent marks and another one for the platform-specific marks. This enables the reuse of the platform-independent marks in the event that the development team chooses another implementation. This also reinforces the idea that portability is an important design criterion when partitioning marking models.