ere’s an interesting coincidence: The “UML Conference,” where I delivered the keynote speech a few days ago, changed its name to “MoDELS & UML.” Similarly, the “UML & Design World” conference where I spoke a few weeks ago was previously called “UML World.” The fact that both these leading conferences have changed their name indicates a big shift in the modeling world that may well lead us away from the one-size-fits-all approach offered by the Unified Modeling Language. One of the new approaches causing this shift is called Domain-Specific Modeling, DSM for short. In this first of a series of articles I will introduce DSM with a short example. Later articles will provide the opportunity to dive a little deeper into the subject, compare it to other approaches, identify characteristics of areas where DSM makes most sense and, of course, show real world examples from the software industry.
Domain-Specific Modeling mainly aims to do two things. First, raise the level of abstraction beyond programming by specifying the solution in a design language that directly uses concepts and rules from a specific problem domain. Second, generate final products in a chosen programming language from these high-level specifications. This automation is possible because both the language and generators need fit the requirements of only one company’s problem domain. In other words, they are both domain-specific.
Raising Abstraction and Productivity
I’ll start introducing DSM by addressing the importance of the abstractions developers work with. Throughout the history of software development raising the level of abstraction has been the cause of the largest leaps in developer productivity. The most recent example was the move from Assembler to Third Generation Languages (3GLs), which happened decades ago. As we all know, 3GLs such as FORTRAN and C gave developers much more expressive power than Assembler, and in a much easier to understand format; yet compilers could automatically translate them into Assembler. According to Capers Jones’ Software Productivity Research, 3GLs increased developer productivity by an astonishing 450 percent. In contrast, the later introduction of object-oriented languages did not raise the abstraction level much further. For example, the same research suggests that Java allows developers to be only 20 percent more productive than BASIC.
Another way for companies to raise the abstraction level is to use software platforms, frameworks or component libraries. These offer abstractions that help in managing complexity, but usually still require developers to program and specify mappings to the components manually, in code. Modeling usually does not help the developer here because most current modeling languages are based on the coding concepts and offer only modest possibilities to raise the abstraction level. For example, UML uses programming concepts (classes, return values etc.) as its central modeling constructs. These are the constructs used most often, and the only ones that generate even skeleton code.
The root problem is that changing the representation of a construct without increasing the abstraction level doesn’t improve productivity. In UML, using a rectangle symbol to illustrate a class in a diagram and later creating the equivalent code representation in a programming language does not provide a higher level of abstraction! Figure 1 shows the relationship of models to code.
|Figure 1. Bridging the Abstraction Gap: Developers have bridged the abstraction gap between an idea in domain terms and its implementation differently over time. DSM allows them to model directly in domain terms without the need to manually map the solution to code.|
If raising the level of abstraction reduces complexity then we need to ask ourselves how we can raise it further. The first step in developing any software (as shown in Figure 1) is to think of a solution in terms that relate to the problem domain?a solution on a high abstraction level (step one). Using UML, after developers figure out a solution (what to do) on this level, they need to map it to a design in UML (how to do it, step two). From there they must implement the design in a programming language (step three). It is remarkable that developers still have to perform step one without any tool support, especially when we know that mistakes in this phase of development are the most costly ones to solve. Most of us will also argue that finding a solution on this level is exactly what has been most complex. Step three, making a model of the solution in UML, has gained little in popularity over since its introduction 10 years ago: 61 percent of developers find it slows them down or makes no difference to productivity (SD Times, 8/15/2004).
While making a design before beginning implementation makes a lot of sense, I believe companies want more from the models than just throw-away specification or documentation that often ends up not reflecting what is actually built. UML and other code-level modeling languages often just add an extra stepping-stone on the way to the finished product. Automatically generating code from the UML designs (automating step 3) would remove the duplicate work, but this is where the UML generally falls short: In practice, it’s possible to generate only very little usable code from UML models.
Rather than having extra stepping-stones and requiring developers to master the problem domain, UML and coding, an ideal situation would allow developers to specify applications in terms they already know and use, then have generators take those specifications and spit out the same kind of code developers used to write by hand. This would raise the abstraction level significantly, moving away from programming with bits and bytes, attributes, and return values, and toward the concepts and rules of the problem domain developers are working in. If this new programming language is a visual one rather than based it on text, then it essentially merges steps one and two, and completely automates step three. That raised abstraction level coupled with automatically-generated code is the goal of Domain-Specific Modeling.
A DSM Example
Figure 2 shows a relatively simple application specified in a DSM language. It is the design for a conference registration application that runs on a SmartPhone. The design is expressed in a language created specially for defining enterprise applications on SmartPhones. It includes modeling concepts such as notification, query, pop-up, and text message?the actual UI widgets and services you already find on a phone. With these and other similar modeling concepts, you can specify both the static structure of applications and their dynamic behavior.
|Figure 2. Conference Registration Application: The model shows a conference registration application in a DSM language intended for enterprise applications on SmartPhones.|
The design provides enough information to automatically generate full code for this application. After drawing the design, the developer can run the generator and execute it on the target. This sample language includes the design rules for phone application development and completely hides the implementation details. You don’t see code concepts in the model.
To be able to design applications this way the developer naturally needs to understand the phone domain. Of course, this particular DSM language is only helpful for designing SmartPhone applications. It is useless for designing a CRM application, a patient monitoring device, or for business rule modeling. However, reducing the design space to just one single problem domain makes it easy to raise the level of abstraction and, as I will discuss in the next section, makes complete code generation possible. As the simple example model demonstrates, the DSM language is much more expressive for designing these specific types of applications than a generic language. The design models made with the DSM language are easier to read, understand, remember, and validate. Perhaps most importantly, it allows applications to be created significantly faster.
Full Code Generation
In my view we should aim at making model-based code generation full: we should be able to generate all the code for the application from the models, and not have to edit the generated code. This completeness has been the cornerstone of other successful shifts made with programming languages, such as compiling source code to Assembly. Ever seen anybody manually edit Assembly and try to keep their C code in synch with it?
Because DSM languages and the way developers write code tend to differ from domain to domain, DSM code generators also need to be specific to a domain. Contrary to the approach that most CASE tools follow in offering proprietary, fixed-code generators, DSM advocates the use of fully open and customizable generators for generating any type of output: code, test cases, documentation, configuration files, etc. The idea is for a company’s expert to have the freedom to define these generators, supported of course in doing this task by the tools offered by DSM modeling environments. Experienced developers usually know better than other developers or tool vendors how best to write code in the company’s problem domain. DSM offers the opportunity here for the rest of the development team to leverage the knowledge of the expert developer. By advocating open language and code generator definitions, DSM aims at letting companies implement changes internally, without being dependent on a tool vendor to make changes for them. The result is a much tighter fit between language, generator and the company’s problem domain.
A Code Generation Example
The code below presents a simple example of a generator definition for a Note dialog like those shown in Figure 2 . The Note opens a dialog with information, like for example “Conference registration: Welcome.” Lines 1 and 6 simply create a structure to hold the generator. Line 2 creates the function definition signature, and line 3 is a comment. Function naming is based on an internal name that the generator can produce if the developer does not want to give each symbol its own function name.
1 report '_Note' 2 'def '; subreport; '_Internal name'; run; '():'; newline; 3 '# Note '; :Text; newline; 4 ' appuifw.note(u"'; :Text; '", '''; :Note type; ''')'; newline; 5 subreport; '_next element'; run; 6 endreport
Listing 1: Code generator for Note dialog
Line 4 produces the call for the platform service. It uses the model data (underlined here for clarity), such as the value for the Text property of the Note UI element (in this case, “Conference registration: Welcome”). Similarly, the modeler chose the ‘Note type’ value in the model from a list of available notification types, like ‘info’ (here) or ‘confirmation’ (used in “Registration made” in Figure 2). The generated line 4 is thus (with modeling data underlined):
appuifw.note(u"Conference Registration: Welcome ", 'info')
Because the code generator automates the mapping from model to implementation, every developer makes the Note dialog call similarly: the way the experienced developer has defined it. Finally, line 5 calls another generator definition to follow the application flow to the next phone service or UI element. This generator, named _next element, is also used by other UI elements similar to Notes.
|Figure 3. Leveraging Expertise: DSM lets experts leverage their knowledge to automate software production and make development tasks easier for the rest.|
In some cases, you may generate all the code directly from the designs. Often, though, this would cause the generation of code with a fair amount of repetition?as you probably have in your existing hand-written code. Making the generator often helps to expose places where lines of code are repeated, maybe with small changes to parameters. You should abstract such code out into what we call the domain framework: utility code or components to make code generation easier. Such a framework forms a thin layer on top of the current platform of in-house and third party components and language libraries.
Figure 3 recaps what I have discussed so far: DSM offers company experts a way to encapsulate their expert knowledge in a new, higher-level modeling language that reflects the problem domain in which developers are working. The expert developers also distil their experience into a code generator that transforms the developers’ designs into code that interfaces with a domain framework layer or software platform. Essentially, DSM lets organizations use the skills and expertise of a company’s best developers to make things easier for the rest.
Why Switch to DSM Now?
DSM is not a new thing. Companies and organizations such as Lucent, NASA, Honeywell, USAF and Nokia use DSM and have gained order of magnitude improvements in developer productivity and code quality. Why then is DSM only now getting all this attention? One part of the explanation surely has to do with the emergence of UML as a standardized modeling language, heavily promoted by the Object Management Group (OMG) as the modeling language for all applications. While the trend promoted by OMG was to go to a unified, standard approach to modeling, DSM went 180 degrees the other way. For a tool vendor it is of course easier to provide an environment that supports just one modeling approach, but the past 10 years of UML show that such models then remain as little more than documentation, and the possibilities for raising the level of abstraction and generating code are pretty limited. UML proponents have realized this and are advocating adding extensions to the UML to make it more customizable. These include stereotypes for labeling, profiles, object constraint language and action language. But what they seem to forget is that adding all this stuff to UML simply makes it even more complex for developers than it already is.
Another reason for the rising popularity of DSM is that in its early days we did not have tools to create domain-specific languages and support modeling with them in a cost effective manner. Those wishing to adopt DSM were left to develop their own tools from scratch based on generic graphics libraries. Considering that building a modeling tool is an effort that requires many man-years of development, DSM was left as an option only for large organizations that could commit to such an undertaking. Nowadays this situation has changed. A growing number of experts (and luckily this time also tool vendors) see DSM as a viable solution that offers developers better tools to deal with the growing complexity of the problem domains surrounding them. The vendors and experts have come together to establish an independent organization called the DSM Forum to spread DSM knowledge and know-how.
DSM copies the principle that made the compiler so successful?raising the abstraction level by removing the need for developers to write Assembly, and letting them work in 3GLs and OOP languages instead. But to make it work for a given company, the principle needs to be applied to that particular setting, tailor-made for the company’s own problem domain and code style. The most feasible way of doing this is to give companies full control over creating and maintaining their own domain-specific modeling languages and generators. Because that investment is made by only one or two expert developers at any one company, it pays off quickly as all the other developers can then model in the new language, and use the generators to create full code.