Steps for Defining DSM
Over the years, I have found that the best way to build modeling languages is to build them incrementally: build a little of the language, model a little, define generators, make some changes to the language, model some more etc.
You can divide the process for implementing model-based development into four phases:
- Identifying abstractions and how they work together
- Specifying the language concepts and their rules (metamodel)
- Creating the visual representation of the language (notation)
- Defining the generators for model checking, code, documentation, etc.
Usually the process starts in this order too. Now I'll look at each step in a bit more detail.
|Figure 1. Physical Structure: This physical structure-based DSM language is used for modeling the hardware architecture in automobiles (based on EAST-ADL)|
Do not think of models as visualizing code; abstractions are essential for the success of any DSL. The most important part is clearly finding the right abstractions. Although it can seem as if low-level language concepts (e.g. mapping a class diagram to a class structure) would be the easiest tactic, it is better to map concepts to the problem domain and thus raise the abstraction level. This way, you can help prevent errors early in the design phase, minimize specification work, and at the same time make the language more suitable for true generation. Describing things in problem domain terms instead of implementation concepts is also good future-proofing. In other words, what is important is what your application does, not how it does it or what language or framework it uses.
2. Language constructs: Obviously, you want your developers to follow the abstractions, obey architectural rules, reuse model components when appropriate, etc. Putting these abstractions and rules right in the language saves your developers from having to refer constantly to in-house "design guidelines" documentswhich are probably out of date anyway. During this phase, you specify the modeling concepts, their properties, and the rules that constrain the use of the language and enforce model correctness. You will generally map the major domain concepts to modeling language objects, while other concepts will be captured as object properties, connections, sub-models, or links to models in other languages.
3. Notation: Next, you need a visual representation of the language, usually a diagram, but sometimes a matrix, table, or plain text. The pictures in this article illustrate representations of different graphical modeling languages where the symbols and icons inside the pictures represent different language concepts. Good DSM tools allow you to define your own notation as it makes models much easier to create, read, and maintain. Using UML-like rectangles for all the different concepts is like trying to understand a foreign language where the only letter is A, with 20 slight variations of inflection!
4. Generators: Ultimately, you want to transform your models into code for interpretation or compilation into an executable. Building a generator is about defining how model concepts are mapped to code or other output. In the simplest case, each modeling symbol produces certain fixed code that includes the values entered into the symbol as arguments by the modeler. Generally, generators also take relationships with other symbols or other model information into account
|Figure 2. The Look and Feel Language: This look and feel language is based on S60 Symbian phones and PDAs.|
Naturally, we need tools that not only provide the editors for modeling with DSM languages, but also support language and generator definition, that share new language versions with developers, update existing models based on language change, etc. Fortunately, these tools already exist, ranging from code frameworks through research tools to commercial environments, with increasing cost corresponding to decreasing work needed to build the language. A list of these tools is available at www.dsmforum.org/tools.html. Using a tool that already offers these features, an experienced developer in a company can thus tailor design languages and generators to a specific domain. Other developers can then design with the resulting DSM languages and tools, and generate actual products from their models.
This article will focus specifically on DSM language creationin essence, the first two steps. The code generator is of course tightly related to your language and defining it is an interesting topic that I'll cover in a future article.
Finding Abstractions and Language Concepts
The goal of defining a domain-specific language is to provide the software modelers and developers with a higher-level language with which they can build systems. When identifying the language concepts, it is of key importance to focus on a narrow application domain and your actual needs for it, knowing that you can change the language when your requirements change. This support for language evolution is essential when it comes to making a choice of what DSM tool to choose. Good tools allow such evolution, automatically updating all the models created previously with the language, whereas with less mature tools all your models are lost.
I recommend that developers who have developed several similar products before in the company’s problem domain or that may have been responsible for forming the component library or framework to be the ones assigned to creating the DSM language. These people are more familiar with the company’s problem domain and will therefore find it easier to identify the modeling concepts and associated rules.
Because every domain differs from another, the language concepts and abstractions between languages differ too. The best places to find your language concepts are the terminology used in your domain, system architecture, existing system descriptions, and component services. In other words, you should borrow from the domain-specific jargon or vocabulary used in your organization. This vocabulary provides you with natural concepts that describe your industry in ways that people already understand; people do not think of solutions in coding terms. Starting from the existing vocabulary also means that there is no need to introduce a new, unfamiliar set of terms, or create a mapping between two sets of terms.
In my experience, creation of a domain-specific modeling language often starts from a certain viewpoint on the domain. Language concepts are then chosen, or their identification is started, based on:
- Physical product structure
- Look and feel of the system
- Variability space
- Domain (expert) concepts
- Generation output
I will discuss each category in more detail and provide some examples.
Physical structures are easy to identify and clearly defined, thus making them a good starting point for language definition. In the case of a power plant or paper factory you will have concepts like valves, motors, sensors, and controls. A valve will have attributes such as 'size' and 'direction', and rules on how it may relate to motors and sensors. Your DSM language should use these same concepts directly as language constructs.
|Figure 3. Spectrum of Variability: Figure 3 shows how the spectrum of variability method shows the range of decisions and features encompassed by the language syntax. (Courtesy of "Generative Programming, Methods, Tools, and Applications," Czarnecki & Eisenecker, Addison-Weseley 2000.)|
Languages based on physical structures usually focus on static declarative modes but may also include behavioral elements. Designs in such a language usually provide configuration data for the rest of the generation process and are usually linked to other models in order to achieve more comprehensive code generation.
Figure 1 illustrates part of a physical structure-based DSM language, based on EAST-ADL, a DSL that focuses in part on describing the hardware architecture in automobiles. The figure shows the architecture for electronic control units (ECU) with processors and memories connected through a CAN bus. The language provides several alternatives for bus types and constraints on the application of buses in the described hardware architecture.
Look and Feel of the System
You can also define a language based on the viewpoint of its end users' navigation and product use. I call this approach basing your language on the "look and feel" of your product or system, although it may include any kind of perception or interaction with the system. A language for defining voice menus can include concepts like 'menu,' 'prompt,' and 'voice entry' as well as guidelines on how these may be linked to achieve user navigation. This type of language is quite easy to build and test, as it has "visible" counterparts in the actual product. The main challenge is in finding the mapping to other non-GUI concepts.
Figure 2 shows an application design in a language based on look and feel. The language targets Symbian-based cellular phones and PDAs, where it allows definition of the behavioral logic of the applications. Look and feel are represented here by using the actual user interface widgets of the phone as well as the services provided by its platform, like the sending of an SMS message or connecting to the web. If you are familiar with using a phone book or calendar on a mobile device, then you will most likely understand what the application does, just by looking at this single model.
Focusing on variability is another approach to start defining a language: you define the language so that variability options are captured by the language concepts, and the modeler's role is to concentrate on the areas that differ between different products or features.
|Figure 4. The Domain Expert Method: Modeling financial and insurance products for a J2EE web app with a DSM language based on domain expert concepts.|
Success in defining these types of languages depends largely on your ability to predict what kind of variation space is needed in future variants. Variability languages are suitable for product-line development, where you often find them. Preparing for language definition comes down to conducting a thorough domain analysis: identifying which abstractions are the same for all products and which are different. The task of the language is then to describe just that which can be different. Static variation is usually easy to cope withdevelopers have been making parameter tables and wizards to choose among alternatives for decades.
Things get more complicated when the parameter choices depend on other parameter choices. In practice, parameter and feature choice approaches usually break down when you also require the ability to create new features, functionality, and variants. DSM offers a solution that supports situations where not all possible product features have been decided upon.
Figure 3 illustrates the spectrum of variability. Wizards and feature-based configuration focus on making choices among known decisions and features. DSM languages do not set choices explicitly but give a practically infinite space to set variation. You do not know all variants, as they can be numerous. More importantly, you can define the language so that it allows you to make new features as well. Naturally, the language should then constrain the modeler to making only legal features and products.
Domain Experts' Concepts
Because domain expertse.g. test or commissioning engineers, configurators, and service creatorsare usually not programmers, a language for them to program with needs to raise the level of abstraction far beyond programming concepts. Languages that are based on domain experts' concepts are relatively easy to define because for an expert to exist, the domain must already have established semantics. You can derive many of the modeling concepts directly from the domain model. The same holds true for some of the constraints.
|Figure 5. IP Processing: Modeling call processing in IP telephony, a DSM language based on its XML generation target.|
shows a language based on domain experts' concepts. For this particular language the modeling concepts are related to financial and insurance products. Concepts like 'Risk,' 'Bonus,' and 'Damage' capture relevant facts about insurances. Using this language an insurance expert, and thus a non-programmer, draws models to define different insurance products. Generators take care of transforming their designs into code for a J2EE web application. This way the expert Java programmer can build the mapping from the language to code once, and neither he nor the insurance experts needs to know the intricacies of the others' area of expertise. The higher abstraction in models using domain experts' concepts also means that the generated output can be easily changed to some other implementation language.
The fifth and last category languages fall into is based on the generation target of the language. While these languages are easy to build, their ability to increase productivity and quality is questionable. I see very little point in modeling a program class, depicted as a rectangle and then editing the details of that same class in a text file. I do recommend this type of language when the generated output is already in a domain-specific language. The best example I can give is those cases that target generation in a particular XML format. The XML schema provides a wealth of information for identifying the language concepts and constraints. To follow the XML metaphor, designs can be considered valid and well-formed right at the modeling stage. Graphical models can also help overcome many of the limitations of XML.
An example of this kind of DSM language is the Call Processing Language (CPL), which is used to describe and control Internet telephony services (see Figure 5). The language constructs include 'proxy,' 'location,' and 'signaling actions,' essential for specifying IP telephony servers. These same concepts are already defined as elements in XML, and the property values of the modeling constructs are attributes of the XML elements. Having generators produce the configuration in XML gives significant and obvious productivity and quality improvements. With the language illustrated in Figure 5 it is far more difficult to design services that are erroneous or internally inconsistent: something that is all too easy in hand-written CPL/XML.