Show in Frame No Frame
Up Previous Next Title Page Contents Search

3.2 The Modeling Language

The single most important asset of a DSM environment is the domain-specific modeling language. To substantiate this claim, let us consider the payback promised by the DSM approach. The labor of the domain experts who create the DSM environment is the original investment on the DSM. The return on investment, then, is a result of the increased productivity of the developers working with the DSM environment. While the code generator and the domain framework are important parts of the DSM environment, they still remain reasonably invisible for the developer, whereas the role of the modeling language is emphasized as the main instrument of the DSM. Thus, the better modeling language we have the more we benefit from the DSM.

The first rule of thumb for creating a domain-specific modeling language is to keep the language as independent as possible from the target code. We know that it often originally appears easier to try to build the modeling language as an extension on top of the existing code base or platform, but this kind of visualization of the code world very seldom lead to a significant rise in the level of abstraction and it definitely does not free the developer to think according to the domain instead of the code. Thus, to achieve the best possible level of abstraction for our modeling language, we need to base it on the domain itself.

First, ask yourself what you want to do with the domain-specific modeling language. When you have set this mission statement for yourself, you can proceed by asking how you can do what you want and what is needed to do that. This analysis leads to the discovering of the first domain concepts that are to be incorporated into the modeling language. For example, our mission statement for the watch modeling language set the following goal: we want to be able to model those static and behavioral elements that constitute a digital wristwatch. Based on this statement, the further analysis soon identified a watch model, display, logical watch and a watch application as the elementary concepts of the watch architecture.

At this early stage of the modeling language definition, one should focus on identification and definition of domain concepts. There are several ways to do this and it is important to understand that usually none of them alone can provide complete coverage. Good results typically require concurrent use of a number of different strategies. In any case, the key success factor in finding the domain concepts is the domain knowledge possessed by the domain experts.

A good way to identify the domain concepts is to study the aggregation structures within the domain and product. The aforementioned elementary watch concepts were discovered in this way. Another method is to try to find the commonality and variability among the products. For example, it is easy to see that the different watch models still share the common concept of button that would suggest button as a probable domain concept for the modeling language. Similarly, we can see that the watch models differ from each other by the number of buttons and features they include, which says something about the configuration space requirement for the watch models.

It is also worthwhile to examine the existing specifications to see if there are any repeating patterns that could be refined further as a domain concept. And don’t forget common wisdom or experience as a source for ideas – our decision to use the state machine as the computational foundation for watch applications and logical watches was based on the fact that it is a widely used solution in the area of embedded systems in general.

The next step after the identification of domain concepts is to assemble them into a modeling language. The language is defined with MetaEdit+ as a metamodel that applies the domain concepts as the semantic structures for the language. The detailed description of the metamodeling process is out of the scope of this tutorial, so for more comprehensive information about the metamodeling please refer to the Family Tree example in the Evaluation tutorial and the ‘MetaEdit+ Workbench User’s Guide’.

Two important aspects should be considered during the creation of the modeling language: layering and reuse. Modeling language development efforts typically start with a flat model structure that has all concepts arranged on the same level without any serious attempts to reuse them. However, as the complexity of the model increases while the number of elements increases, the flat models very seldom are suitable for presenting hierarchical and modularized software products. Thus, we need to be able to present our models in layered fashion.

Watch model architecture

Figure 3-2. Watch model hierarchy

A partial illustration of the watch model hierarchy is presented in Figure 3-2. The watch model hierarchy consists of three layers. For the top-layer models we use a proprietary WatchFamily diagram type to present the static high-level configuration of each watch model. On the two subsequent layers we employ the WatchApplication diagram type to present the dynamic variability within the logical watches and watch applications. As each additional diagram type increases the complexity of the modeling language, it is normally good practice to design diagram types so that they can be applied recursively on more than one layer. On the other hand, if the semantics of two consequent layers are different, two different diagram types are the recommended solution.

Another aspect that influences the layer structure is reuse. The idea of reuse-based layering is to treat each model as a reusable component for the models on the higher level. In this kind of solution, the reusable element has a canonical definition that is stored somewhere and referenced from where it is needed. In the watch example, the whole layering is actually based on this principle. Each watch application is a true model component that can be referenced from any logical watch. Similarly, each logical watch can be attached to any concrete watch model.

Reuse can also happen regardless of or in addition to the layering. Typically we also want to reuse concepts within or between the models. The concept of a display function is an example of reuse within a model. Defined once in a WatchApplication diagram, each display function can be referenced by any state within the same diagram. Reuse between the models is needed when the same concept appears on several models. Examples of this kind of concept within the watch example are the buttons. While it is possible to create a new button concept for each state transition, it is much better idea to reuse an existing one. It is not only faster to use buttons in this way, but it also makes it easier to propagate possible future changes (like changing the name of the button). This kind of reuse differs from those described above in the sense that there is no canonical definition for the reusable element. It can be considered as a floating concept that exists as long as it is instantiated somewhere.

The last step during the initial development of a domain-specific modeling language is the finalization of the language. Typically this means the extension of the language with concepts that are required for code generation, component interfaces, consistency checking and documentation. In the watch example, the inclusion of the watch domain framework code as included components in WatchFamily diagram is an example of this kind of late addition. With this solution we wanted to ensure that the framework code is always available for the code generation. Otherwise, and probably a bit surprisingly, no other code or documentation generation related additions or modifications to the original modeling language were needed.

Show in Frame No Frame
Up Previous Next Title Page Contents Search