18.1 Compiling the Models: The Bookstore


The online bookstore case study we have developed throughout the book can be compiled and executed. That's the whole point.

However, there are many possible implementations. For example, we could choose to use a Web service written in Java running on an EJB Web server that uses XML messages to communicate, with a relational database for persistence. Alternatively, we could build a set of active server pages, using an ActiveX DLL written in C++ with an API for receiving messages and an object-oriented database for performance reasons. We could even use Perl scripts and a pile of files.

Any one of these implementation choices is valid if we can make it work and the choice we make will in no way change the Executable UML models we have built. There is complete domain separation between the model compiler domain and the bookstore application domain. All we need is an Executable UML model compiler.

Definition: An Executable UML model compiler compiles an Executable UML model into a runnable implementation.

A model compiler comprises a set of mechanisms that manages and localizes the run-time system, and a set of rules for how to weave the Executable UML models together.

18.1.1 Mechanisms

Mechanisms are library-like components that require no specialization: ways to manage a class extent, intertask communication functions, warm-standby logic, and the like. This library of mechanisms is determined by the model compiler, and the mechanisms contained therein fit together to make an Executable UML virtual machine.

The model compiler must therefore provide an implementation mechanism for each of the elements of Executable UML. For example, Executable UML has elements called "classes," "attributes," and the like. A model compiler provides an implementation for each of those elements. One implementation could be a class and private data members in C++; another could be a struct and a set of functions in C. It is possible to implement the functionality of a class in silicon. Each of these is a valid implementation.

Similarly, Executable UML has active elements such as "signal" and "action," and the model compiler must provide an implementation for these too. Hence, a call to a SignalTaker function could implement a signal synchronously within a single task, as could the sending and receiving of a particular kind of message between tasks. A procedure can be implemented as a function or subroutine, and so on.

The model compiler must include mechanisms to

  • create, store, and retrieve data

  • execute procedures and their actions

  • generate signals and receive events

  • establish delays and determine absolute time

The model compiler can implement these mechanisms any way it chooses: hardware, software, or wetware. The resulting implementation will have certain performance properties depending on the decisions made about concurrency, tasking, number and type of processors, use of memory, and so on.

18.1.2 Archetypes

The rules for weaving the Executable UML models together are stated as archetypes.

Definition: An archetype is a fragment of data access and text manipulation logic that states formally how to embed an Executable UML model into text.

The text produced by an archetype is often recognizable by a person and by a compiler as a programming language. This means an archetype can be written to target any language, C++, Java, Smalltalk, or even COBOL.

The text produced by an archetype need not be a traditional programming language as such. An archetype could generate Java byte code, completely bypassing the Java compiler, or an archetype could generate assembly code. Archetypes can be written to target hardware description languages such as VHDL or RTL. In fact, archetypes can be written to generate anything from passive metrics on the size of the models to document macros to if you know the syntax of the language Klingon.

The text produced by the model compiler need not be human-readable. Once the text is generated, compile it and run it. There is no reason to read it, and certainly no reason to change it. If there is a problem with the resulting code, change either the domain model or the model compiler. Changing the output of a model compiler is just as insane (and very occasionally justifiable) as changing the output of a Java compiler. Don't even think about it.

The archetypes access a repository containing arbitrary Executable UML models. The structure of the repository is defined by a metamodel.

Definition: A metamodel is a model of a language expressed using a modeling language.

For example, the model of Executable UML is expressed using Executable UML. This model of Executable UML is the so-called metamodel.

The metamodel contains classes such as Object (abbreviated O_OBJ) and Attribute (O_ATTR) with an association R102 between them. It also contains classes for state machines (SM_SM) and Events (SM_EVT) associated by R502. The instances in the metamodel capture the entire semantics of the application, including and especially the action language.

Models, Metamodels, and Metametamodels

The model of Executable UML (i.e., the metamodel) is a model like any other. There is no difference in the meaning of class for the class Product and the class Class. They're both just classes, and one just happens to be describing itself.

The term "metamodel" is useful to distinguish between the model of the bookstore, say, with classes Book, Product, Selection, and so on, and the model that captures the bookstore model, which is to say the metamodel. We can construct useful sentences such as "The class Book is captured in the metamodel as an instance of the class Class whose name is Book." In this case, "meta-" is being used appropriately as a relative term to distinguish between the two models. Using "model" instead of "metamodel" would be confusing, more confusing even than saying "an instance of the class Class."

However, when we come to discuss the metamodel itself, some writers talk of metaclasses and meta-attributes and meta-associations and metathis and metathat. The result is an overload of metawhatever that adds no value whatsometa-ever.

What happens when you build a metamodel, as you quite reasonably might, of the metamodel? Do you get a metametamodel with metametaclasses and metameta-associations? Sadly, the answer is Yes. And metametameta? Let's not go there.

The instances of these (meta)classes capture the classes, attributes, state machines, and events in the bookstore applications, so that an archetype language can traverse these instances.

18.1.3 Archetype Language

An archetype language is a combination of data-access language and string-processing language. It's part data access because we need it to access the repository, and part string manipulation because the outputs are strings that may require some work, such as stripping spaces or applying a capitalization convention. An example is depicted in Figure 18.1.

Figure 18.1. Highlights of an Archetype that Creates a Java Class

graphics/18fig01.gif

In the archetype language, every line that does not start with a period is just text. The output is exactly the same as the input, so if you write Java, you get Java.

Each line that starts with a period is a command to the archetype language processor. The .select statement accesses a repository containing a metamodel populated with instances from the model. A statement such as


.select many attributes related by object->O_ATTR[R105]

selects all the attributes related to the instance handle object across R105. The result is a set of attributes for the class (called attribute in the example) for which we are generating code. This set may then be iterated over, thus:


.for each attribute in attributes
  private ${attribute.implType} ${attribute.name};
.end for

Once data from the repository is accessed, it can be substituted onto the output stream using ${…}, as shown above. The result is a list of attribute types and their names, each terminated with a (clear text) semicolon.

The metamodel and the archetypes go "all the way down" to the action language. We are not creating frameworks for handcoding actions, but compiling the entire executable model into a target language. But this is not a job for amateurs.

The result of applying the archetype to a portion of the bookstore model can be seen in Figure 18.2.

Figure 18.2. Java Class Created by Applying Figure 18.1 Archetype to the Bookstore Models

graphics/18fig02.gif

By modifying the mechanisms or the archetypes, you have complete control over the generated code.



Executable UML. A Foundation for Model-Driven Architecture
Executable UML: A Foundation for Model-Driven Architecture
ISBN: 0201748045
EAN: 2147483647
Year: 2001
Pages: 161

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net