Executable UML: A Foundation for Model-Driven Architecture

As we build the executable UML model, we need to verify its behavior. This work takes place continuously; we test the models as we go along. Similarly, we can compile the model into an implementation as we proceed, checking that the performance of the generated code is adequate for the system.

2.3.1 Model Verification

Having worked our way through all of these steps, we now have the executable UML work products. The very intent of executable UML is to provide a way to prototype the domain without having to construct a complete product. We can verify the finished system without making any decisions about software structure. We can be certain that we have designed the proper behaviors without being concerned with the performance of our network and database. We can also use this approach to test the performance of specific underlying services without needing to have the entire application in place.

There are two kinds of verification. Static verification is like a syntax check that a compiler does. In the early eighties, a lot of work was done on "structured editors" for programming languages. The goal was to provide a way to enter the code without syntax errors to make the programmer more efficient. By using a modeling tool that truly understands the formalism of executable UML, the amount of human intervention in static checking will be less than if you use a general-purpose drawing tool or "flexible notation" modeling tool.

Dynamic verification requires real objects and a scenario to execute with real values. Each scenario should correspond to an instance of a use case or a portion thereof, though the scenarios are built more from the models than the original use cases from which the test cases were derived. When the scenario is executed, the resulting instances and their values can be checked for correctness with the user and even changed contemporaneously.

2.3.2 Model Compilation

A model compiler turns an executable UML model into a implementation using a set of decisions about the target hardware and software environment.

The model compiler is therefore an implementation of a subject matter that has the conceptual entities required to execute an arbitrary UML model.

Select a model compiler appropriate to the performance requirements of your solution. Direct the model compiler so it treats each part of the application in the manner you desire (allocation of components, persistence, state execution strategies, static populations that can be optimized in storage, in short, any feature of the model compiler that can be applied differentially to the application).

Then each time you compile your models, you have a running system on which you can verify the behavior of the application and other domains and verify that the performance is adequate. If performance is not adequate, re-allocation of the application components, or even a new model compiler, could help.

The worst case is that no known model compiler meets the performance properties required. In this case, you can hand-code performance-critical portions of a problem and "wrap" them to link up with the generated code. In all cases, 100% of the model is generated, even if the generated code represents less than 100% of the system. Do not modify generated code.

You could also purchase a model compiler that is closest in performance and modify it to generate higher-performance code uniformly. This book does not address this topic.

2.3.3 Iterating Verification and Execution

The last two steps, verification and applying the model compiler, both concern system execution. The former allows for model interpretation so that you and your users can check that the system behaves as desired. Any errors found here will lead to reconstruction of the domain models.

Model verification should take place as each increment of a subsystem is modeled. Executing the model increases our confidence that the model does the right thing. Such verification should be carried out continually as the models are constructed. Indeed, you may build the test cases before you build the models.

The second step, applying the model compiler, is akin to program compilation. Because there are several model compilers available, you may choose to change the model compiler if the performance is not adequate.

Of course, the model being compiled has to be "efficient." A better model compiler won't fix performance problems caused by building a statement for every transaction, instead of grouping transactions monthly. On rare occasions, you may need to modify the application domains to meet performance constraints caused by the model compiler.

Категории