Software Factories with Domain Specific Languages

Creating and Integrating Domains

A few years ago, we still believed in one customizable specification language called UML that could be used for most systems specifications. Of course, we cannot say that this approach does not work. I would just say that it almost works. Eight years ago, we did develop a software factory based on UML profiles and Rational Rose add-ons. Though the factory is still in use, I have to confess that building such factory was not an easy task. And, the resulting modeling experience is not quite as precise, unambiguous and sexy as I would like it to be.

Today, and for many good reasons that Jos clearly explained here, we understand that it will be more effective to use languages and development environments that are specific to the domain at hand. In practice, we are hopefully transitioning from generic languages and development environments to domain specific languages and software factories.

Modeling a User Experience Designer DSL using the Microsoft DSL toolkit

 

The remaining of this article is based on different experiences with the development of Software Factories, including Domain Specific Languages, using the Microsoft toolset.

In particular, we will talk about creating and integrating domains.

 

Software Factories Development: The Domain of Creating Domains

Banking Software Factory

The development of a Banking System can be eased by using a domain specific Banking Software Factory. This would include some banking specific assets (Banking database schema, financial data contracts, DSLs, generators...).

 

Factory Factory

Similarly, the development of a Software Factory System is supported by some Software Factory development assets. These assets materialize in what some call a “Factory Factory”.

Building a Software factory development brings of course some very “domain specific” challenges.

Typically, while you are creating a Banking System, you often create also a testing system, a deployment system for it.

While you create a software factory, you have to add to that list the development of a software factory system.  And you also need to add a software factory testing system, and a software factory deployment system.

One challenge here is that

·         On one hand, we are developing a software factory system.

·         On the other hand, that software factory system needs to automate the development of another system.

This must be achieved in a very rigorous fashion. To build software factories, we need more than technology and APIs. We also need a well defined software factory development process (with automated guidance) and a clear refinement path.

The process includes:

·         The iterative definition of the subsequent application states that the Banking System solution will reach during the development life-cycle (the “application assets”).

I should say “very iterative definition”, because when you start building your software factory, you only know some ultimate variants of a reference banking solution. Every step in the middle of the development life-cycle, all the intermediary states, all the development stages in the development of the banking solution tend to appear, disappear and mutate while you are building the factory.

·         The definition of the development tools that the developer of a banking system (the software factory user) will use. For example, the Banking System developer will use a recipe to add a Payment Web Service model, a DSL to configure the service, and a generator (Text template) to generate the code skeleton.

As a result, the state of the Banking System solution evolved from “No Payment Web Service” to “Payment Web Service skeleton generated”.

Developers’ actions and software factory actions lead the banking system solution to evolve step by step, state after state. And these states need to be iteratively but precisely defined. Without such precision, you don’t really know the tools that you will need to make your solution evolve from state to state.

 

Avoiding Domain Specific Islands

When composing some music for guitar, you typically refer to a domain specific language (tablature for guitare) like this:

[F] Yesterday, [Em]     all my  [A7] troubles seemed so   [Dm] far away….

 

 

And when writing music for piano, you use another domain specific language like that:

Though these languages are different, they both describe notes that belong to an exact same set of notes. Both languages share some common and precise semantics. Hence the guitar and the piano can play together in harmony.

Similarly, while creating domain specific languages, a challenge is to avoid creating domain specific islands. When putting these languages together, we need to avoid some DSL cacophony.

Each domain, whatever it can be, has many concepts in common with other domains. Some common concepts need to be simply “recognized” by the software factory users. Some other concepts need to be formalized and become the integration points between different domains (viewpoints/work products) in a software factory or between software factories. So we also need some standards and guidelines for integrating semantics and notations across domains.

We could even have some recommended strategies for consistent work product (e.g. code) generation and synchronization.

 

To illustrate this domain specific challenge, I will use a DSL-based User Experience Designer that I created with my friend Matt Smith at the Unisys/Microsoft alliance. This was developed thanks to the support of Michael O’Connell, our manager of the Unisys Technology Center in Redmond, who had the vision to make this all possible.

 

The main features of the designer included

 

The User Experience Designer was created to ease communication with off-shore teams. Indeed, given the distance and the different time zones, our colleagues need more than a draft requirements document and a few screen shots to figure out what the user interface should be. They need something precise and unambiguous.

 

Many user interface experts consider that an executable user interface prototype is the most precise user experience specification that one can provide to a customer. But the issue is how to get to such prototype. How to visually structure the design and the behavior of the entire user experience step by step? How to provide a synoptic view on the design and how to zoom into details (down to the real user interface implementation) only when needed? How to comprehend both the structure and the behavior?

The Rational UML-based User Experience Modeling approach provided some answers. However, as the UML language is generic, it could not provide the expressiveness needed to precisely address the particularities of a specific platform like Windows Forms, ASP.Net, AJAX, WPF etc…  Although the UML approach was excellent for its time, it was a bit as if every article in store was wrapped in the exact same paper with just a name on it to differentiate.

As another extreme, the ASP.Net User Experience Designer illustrated below was a first step that we made, at the Unisys/Microsoft Alliance, towards a domain specific language dedicated to ASP.Net user experience specifications. Our DSL is purely and only domain specific. This is the advantage and this is also the problem.

One of the main benefits of DSL authoring, is that we can easily integrate all the familiar ASP.Net terms, shapes and icons. And we can also integrate the precise modeling behavior that we need. This makes the DSL very easy to use for both the user experience analyst and the ASP.Net developer.

 

The following figure illustrates the context where the DSL-based User Experience Designer is used.

 

And here are a few pictures that illustrate what the User Experience Designer can do:

 

The User Experience DSL Designer Toolbox

 

Modeling the structure of an ASP.Net Master Page

 

Modeling the structure of an ASP.Net Web Form that uses the master page

 

Mapping a Web Form to a Master Page and its Content Place Holders

 

 

Modeling the dynamics the of ASP.Net User Experience

 

As we can see, such domain specific expressiveness is essential.

Within our own single domain, we can easily and precisely map elements like “Web Form” and “Master Pager”.

But we know that the DSL will not be used in isolation. It needs to integrate with other DSLs that together belong to a larger domain. To illustrate the issue, let’s take the example of a Software Factory for creating Distributed Systems. The target distributed system could include, notably, some web services and a choice of one or several types of user interfaces: A Smart client, a Web client, a Voice client, a TV remote control client etc…  (such variability is also needed for selecting between different types of persistency mechanisms).

Hence the Distributed Systems Software Factory could provide a choice of user experience designers (DSLs) addressing specific platforms. Or better, the Distributed Systems Software Factory could provide a choice of User Experience Software Factories. And each User Experience Software Factory should include some platform specific DSLs.

 

So the key is to create DSLs and Software Factories that, on one hand are domain specific, and on the other hand are “compatible” so they can integrate with each other. And when we say “compatible”, that involves more than technologies and APIs. We also need compatible semantics, terminology and look and feel. This is essential if we want the Software Factory user to experience some natural continuum within the development life cycle.

Now to make these things compatible, we will need to follow some recommendations, guidelines or standards. So, coming back to our user experience designer, the DSL author will need some common approach for creating homogeneous user experience languages across different platforms. Such approach includes some reference semantics, ontology and specification styles. You will find information on a more comprehensive approach at this location.

 

Code Generation

Another thing that we learned is that the generation strategy and the selection of the target platform will make code generation more or less useful. Today, generating ASP.Net code (as shown in the picture below) would not be a good choice because, once you start changing the generated code by hand (and you need to), the model gets completely out of sync.

 

 

Today, a possibly better alternative would be to use an XAML-based user interface layout (like in WPF). The XAML could then be shared by the user experience modeling tool that provides you with the synoptic view, while the form designer would present you the details of the real graphical user interface.

 

As a conclusion, I am very eager to have a Microsoft “Software Factory Factory” installed on my computer. And I would be happy to see a software factory development process as part of its documentation and automated guidance. I believe that this development process should include some reference semantics and ontology and recommended specification styles to ease integration and homogenization between different domains. Strategies and guidelines for code generation and synchronization would be welcome as well.

 

 

 

 (C) 2005-2007 Alain De Preter - Tous droits réservés - All Rights Reserveds