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.
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...).
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.
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.
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