Using model-driven development for agile embedded apps: Part 3 - Action models & model translation

Bruce Powel Douglass

December 28, 2010

Bruce Powel Douglass

As used in model driven design, actions are primitive statements such as augmenting a variable, creating an instance, or sending a message. Actions show up in three primary places in a UML mode: as actions on a state machine, as actions in an activity diagram, or as statements in a method body.

The OMG specifies action semantics— that is, the kinds of things that an action language must be able to state—but does not specify an action language. An action language meets the required action semantics but also provides a syntax.

What most people mean when they use the term action language is abstract action language—a language that is not meant to be directly compiled into executable object code but rather is intended to be translated into a concrete action language for compilation.

As it happens, any third generation language (3GL) such as C, C++, Java, or Ada can be used to express the action semantics for a UML model. The OMG does not currently define an action language, although there is some work under way in this regard, but nothing is expected to emerge until late 2009 or possibly later.

The vast majority of modelers use, and prefer to use, the same concrete language in their models as they plan to use for the implementation. However, there are some advantages to using an abstract action language. If you plan to implement the model in multiple concrete languages, or need to allow for the possibility of reimplementing the model in a different concrete language, then an abstract action language provides some real benefit.

Abstract action languages are not without their drawbacks. First, for right now, they are vendor-specific and will be until and unless the OMG releases a standard. That ties your models to a specific tool even though UML models may be exchanged if the tools adhere to the XMI standard (in the upcoming section “XMI”). Second, many developers don’t want to learn another language at the same level of abstraction as the implementation language in which they are already experts.

An even more serious issue is the difficulty in debugging. If you discover a problem in the PSI, you can’t change the PSI and import those changes into the model, because the actions are specified in a different language. You need to fix the abstract action language and then forward-engineer to test the code. There may not be an obvious mapping between the abstract action language and the implementation language, so you will have to think about how to cast the problem in the action language to produce the design implementation language result.

Since the two languages are at the same level of abstraction, this may be more trouble than it’s worth. Last, the most serious complaint is that unless the action language includes a decompiler (translator from the implementation language to the action language), you can never touch the PSI without breaking the connection between the model and the code. While forward engineering (generation of code from models) is the primary workflow that must be supported, it seems draconian, as well as unnecessary, to completely disallow the reverse workflow.

As I have mentioned, most developers using MDA today use the target implementation language as a concrete action language in the model. This does mean that if the model must be retargeted toward a different implementation language there is some work to do, but using a concrete action language eases the debugging while simultaneously enabling reverse engineering when necessary.

Model Transformation

With all these models around, how does one ensure consistency? MDA approaches this problem through model transformation. Models may be transformed manually, to be sure, but emphasis is placed on automating these transformations as much as possible. Primarily models are forward-transformed (CIM to PIM to PSM to PSI), but sometimes backward transformations are performed as well.

There are many ways these model transformations can be done. The most useful are by metamodel mapping, by marking and transforming the model, and by elaborating the model with design patterns.

Metamodel Transformations

Metamodel transformations are done by creating PIM- and PSM-specific metamodels and transforming a metaclass from one into the metaclass for the other. The basic idea is shown in Figure 2.8. The PIM is captured in a domain-specific modeling language (most likely a UML profile) that contains domain concepts for the platform-independent application semantics. The PSM is defined using a different metamodel (also likely a UML profile). The mapping rules identify which metamodel elements in the PSM are created from which metamodel elements in the PIM.

Figure 2.8 Metamodel transformations

The disadvantage of this is the work involved in creating two different metamodels and the mapping rules that define the transformation between them, as well as constructing the translator. The advantage of the approach is that once this work is done, many metamodels can be transformed easily. This approach is not used as often as the other approaches discussed here.

Another approach is to mark the one model with “design hints” and use a translator that uses the design hints to create the PSM by applying transformational rules to the marked elements (see Figure 2.9). This is very similar to the previous metamodel transformational approach discussed but is less work to implement. In this approach, marks are added to the source model (usually the PIM).

These marks are almost always either stereotypes (such as the «trace» and «active» stereotypes mentioned previously), tags (user-defined name-value pairs), or constraints (user-defined “well-formedness” rules). These three elements form the lightweight extension mechanisms in the UML used to define profiles, a topic that will be discussed soon.

For example, some classes in the PIM might be marked as «distributed» and the translator might generate CORBA or DDS (Data Distribution Service) interface description language (IDL) for the marked elements. Or an association on a class might be marked «IPC» to indicate interprocess communications. 

Figure 2.9 MDA model transformations

The third, and most common, approach for generating the PIM is through the manual or semiautomated application of design patterns (see Figure 2.10). A design pattern is a generalized solution to a commonly recurring problem; that is, to be a design pattern, it must be generalizable and must still make sense when the specifics of its application are removed. It must also address a concern that reappears in a variety of contexts; that is, it must be reusable. 


Figure 2.10 Design pattern model transformations

Another useful definition for a design pattern is that it is a parameterized collaboration. It is a set of collaborating object roles, some of which are the formal parameters of the pattern. These parameters are object roles typed by classes that will be replaced by classes from the PIM. The process of substituting the actual parameters (classes from the PIM) for the formal parameters (classes in the pattern) is called pattern instantiation.

< Previous
Page 1 of 3
Next >

Loading comments...

Most Commented

Parts Search Datasheets.com

KNOWLEDGE CENTER