Executable UML (Mellor and Balcer 2002) is a profile of the UML that defines an execution semantics for a carefully selected, streamlined subset of the UML. The subset is computationally complete, so an executable UML model can be directly executed. Modeling rules are enforced not by convention but by execution: Either a model compiles and runs, or it doesn't.
All diagrams (for example, class diagrams, state machine diagrams, and procedure specifications) are projections of an underlying semantic model. UML models that don't support execution, such as use case diagrams, may be used freely to help build the Executable UML models.
The essential components of Executable UML are illustrated in Figure 9-1, which shows a set of classes and objects that use state machines to communicate.
Figure 9-1. Essential elements of Executable UML
Each state machine has a set of procedures, each of which in turn contains a set of actions. These actions are triggered by the state changes in the state machines that cause synchronization, data access, and functional computations to be executed.
A complete set of actions makes UML a computationally complete specification language with a defined abstract syntax for creating objects, sending signals to them, accessing data about instances, and executing general computations. An action language concrete syntax provides the notation for expressing these computations. Because Executable UML is computationally complete, it can be used as a platform-independent language to specify any subject matter in the system.
The difference between an ordinary, boring programming language and a UML action language is analogous to the difference between assembly code and a programming language: They both completely specify the work to be done, but they do so at different levels of language abstraction. Programming languages abstract away details of the hardware platform so you can write what needs to be done without having to worry about the number of registers on the target machine, the structure of the stack or how parameters are passed to functions, and so forth. Action languages abstract away details of the software platform so you can write what needs to be done without worrying about distribution strategies, list structure, the niceties of remote procedure calls and the like. (See the sidebar Coding Versus Actions.)
As the existence of standards made programs portable across multiple hardware platforms, so too would the existence of an executable UML standard in MDA make models portable across multiple software platforms.