15 lessons learned during the development of a Model Driven Software Factory

Looking back - Lessons learnedDo you believe in Model Driven Software Development? Do you believe in modeling languages on a higher abstraction level and automated transformations to an executable business application?

I see Model Driven Software Development as an important part of the future of software development. However, I also see a lot of people struggle with actually using Model-Driven techniques and applying them in their daily business. It isn’t trivial to build a successful Model-Driven Software factory (MDSF). In this article I want to share 15 lessons I learned during the development of a successful Model Driven Software Factory.

For more background information about Model Driven Software Factories or designing Domain Specific Languages please read the linked articles first. In short: a Model Driven Software Factory let’s you design a software application using high level models. These models are automatically translated into a working software application.

So, what’s important to remember when building your own Model Driven Software Factory?

1. An MDSF is a product, product development starts with a customer need

A Model-Driven Software Factory is a product, even if you only use it within your own company. Hence, you should treat it as a product. Make sure it fulfills a customer needs. Yes… your colleagues are your customers if you’re in the meta-team and they’re in the project team! Don’t just build a code generator or interpreter because you want a technical challenge. Don’t start designing a DSL because it sounds cool. Start building your MDSF by executing a proper ‘market’ analysis. Finish it as a product (see lesson 10).

2. Make a clear choice about your target user

Your MDSF is based on Domain-Specific Languages (DSLs). A DSL is a language tailored to (..surprise…) a specific domain. This means you need to have a specific target user in mind when designing a DSL. Think about the user you want to target with your MDSF early on. You probably want to target multiple types of users with different skill sets, all using a part of the DSLs (separation of concerns).

Besides the focus of your languages, the main focus of the MDSF can make a huge difference too. There’s quite a difference between an MDSF focusing on a domain expert (from the business) as its main user and an MDSF focusing on developer productivity. Think about integration with other tool sets, usability, etc.

3. Think about a methodology early, it will influence your DSL design and tooling

When designing a DSL you should have a methodology in mind. In what order (i.e. what process) does the user need to instantiate the domain concepts? How does the user design and build software? A methodology need to be tailored to your target user and it should influence your DSL design and your tooling. Example methodologies for building business applications are:

  • Process-driven: the user of your MDSF starts with designing a business process. From this process, parts of the information model and UI model can be generated and designed in more detail by the user.
  • UI-driven: the user of your MDSF starts with designing the user interface of the application. From this UI, parts of the information model can be generated. The user can add logic and process flows to complete the application.
  • Information-driven: the user of your MDSF starts with designing the information model (or: domain model). The other parts of the application are build around it. The UI, for example, can be partly generated.

For more food for thought about approaches to design business applications see The Process-centric vs. Information-centric approach to SOA.

4. Use model checks to prevent errors early

Make sure to define model checks to prevent the user from making modeling errors. Model checks can be domain-specific and can contain a lot of knowledge if your languages are specific enough. Hence, model checks can guide users and prevent errors early. They are especially useful in keeping different parts of your model (possibly defined in different DSLs) consistent. Without model checks it can be quite difficult to detect the source of an error in a generated application (is it an error in your generator, the static framework, the model?).

5. Make DSLs as declarative as possible

A declarative DSL defines the what instead of the how. In other words: it describes the function of an application, not how to implement it. Declarative DSLs make it possible to really abstract away from implementation details and to make it possible for non-programmers to be part of the software development process.

6. Prevent property explosion

Your initial DSL will probably be a nice, clean, tailored language. However, when more people are going to use your MDSF and start giving you feedback, you will probably start extending your DSLs to create more options for your users. I can promise you a property explosion! Within a few releases of your MDSF your DSLs can grow into big languages with lots of options which are difficult to understand for new users.

The first way to prevent an uncontrolled property explosion is to make sure to analyze the root cause of a feature request. Use a method like the 5 Whys to detect the real question of your users and design a solution for it. Take your time to come up with a solution which doesn’t compromise the design of your MDSF. And don’t forget… your version control system contains a revert function!

7. Create flexibility for unforeseen uses

An MDSF can introduce a double release cycle problem. When a customer asks for a change in a software application it can take two release cycles to come up with a solution. If the change cannot be made without changing the MDSF, first a new version of the MDSF need to be released. Afterwards a new version of the application need to be build and released.

In the same way an MDSF can create a lock-in situation. If it isn’t possible to finish an application without changing the MDSF you’re stuck.

To prevent these issues you need to design flexibility for unforeseen uses in your MDSF. Make sure the users of your MDSF can finish their application even if the functionality they need isn’t designed in your declarative DSLs. For example: add integration with 3GL languages like Java or C#. In this way your users can always finish their application by writing 3GL code in addition to using your DSLs.

8. Do not only focus on the development phase

When building an MDSF you shouldn’t only focus on the development phase. Model Driven Development (MDD) aims to improve the software development process by providing abstraction (higher level modeling languages) and automation (code generation or model interpretation). However, MDD tools are almost always only focused on the development phase of a software development process. Other phases like deployment and maintenance need attention too!

Deployment, for example, can be very slow. Customers will ask for compliance with code style, architecture, server configuration, etc. See Why Model Driven Software Development isn’t fast enough and how to fix it for more on this topic!

9. Always look at existing standards first

Designing Domain-Specific Languages is fun! It’s even more fun when you see a lot of people improving their productivity using your DSLs. An easy trap when enthusiastically designing DSLs is to forget to search for existing languages and standards first. Don’t try to innovate in fields were good standards exist and no abstraction can be made.

10. Put effort in documentation, training, and templates

As stated in lesson 1: an MDSF is a product. Hence, finish it as a product. Make sure to provide documentation and training to your users. Templates are a great way to guide users in using your MDSF. Providing documentation, training, and templates will save you a lot of distraction (you can focus on developing the next version of your MDSF) and is the key for quality end-results. The latter is important! You MDSF will get a bad reputation if users use it badly and deliver poor quality to their customers.

11. Be always backwards compatible

Nothing is more frustrating than losing work. Make sure to be always backwards compatible. If your users open their models in the next version of your MDSF everything should work as before. You can use the following techniques to be backwards compatible:

  • Automatically convert the models to the new version for small changes in your MDSF.
  • Deprecate model structures and provide alternatives for breaking changes in your MDSF. Use model checks to guide users in using these alternatives.

12. Do not only test the technical implementation

You should of course test your Model Driven Software Factory. Create automated tests using test models and learn from reported bugs (add them to your test suite before fixing them). However, do not only test the technical implementation. You should also test:
Backwards compatibility, see lesson 11.

  • Usability, for both the modeling environment and the user interface of resulting applications.
  • Productivity, is your MDSF still a way to boost the productivity of its users or is it evolving into a complex web of language structures no one comprehends? Do your users actually see productivity gains?
  • With new users frequently, to make sure your MDSF is still easy to use.

13. Start doing lighthouse projects yourself

Your excellent MDSF is ready, version 1.0 has been launched. What to do now? How to persuade people to start using your MDSF? People won’t start using your MDSF (even if you’ve build an MDSF for people in your own company) without showing them what the real advantages are. You should therefor do some lighthouse projects yourself. Find a customer in need for an application and build it. Amaze people by delivering quality software in no-time due to the use of your MDSF.

14. Integrate community tools in the modeling environment

In lesson 10 we talked about documentation, training, and templates. Provide these elements online. Create a community around your product. Let people answer each others questions, share templates and plugins, etc. A way to engage community users is to integrate community tools directly in the modeling environment. Show questions and answers, share and download templates with a few mouse clicks, etc. Also think about integration with social media. Who knows… maybe you’ll create something viral.

15. Give people incentives to use your product and to be active in your community

Why should people use your product? The answers of course starts with a great product and measurable results. You should also put effort in a licensing model (if you’re a tool vendor) or in management support (within your own company). Give people incentives to be active in your community. You want them to answer questions, publish templates and plugins, etc. You can think about reputation (see the success of stackoverflow) or more tangible revenue models.

This article is based on my talk at Code Generation 2010. See the slides below for an overview of the full presentation.

Photo by rachelliquindoli

8 Comments Added

Join Discussion
  1. Tiny Tim September 29, 2010 | Reply

    Nice article! Here is a small typo: “than loosing work” -> “than losing work”

  2. Johan den Haan September 29, 2010 | Reply

    Thanks Tim! I just fixed it.

  3. Marino December 3, 2010 | Reply

    Great post, second time I read it!

  4. Software Factory Grrl February 25, 2011 | Reply

    Thorough article, thanks. There’s some useful info about Software Factory architecture and design patterns on the following site for further reading – http://www.xosoftware.co.uk/Articles/WCSFDesignPatterns/

  5. Peter Windsor December 2, 2011 | Reply

    Rather late coming to this, but really appreciated it. We’re just coming to the end of a project that’s built a model driven platform (not really a full factory) and your article very much fits with my reflections on what’s gone well (ie we happened to do what you recommend, eg being very declarative) and what’s proved difficult (eg, despite good intentions, not having enough documentation and training material). A couple of points to add. First, we built our platform alongside the first product that’s using it (rather more than a lighthouse). That’s helped ensure we built what was needed and meant we hit lessons 1, 2, 3, 4, 7, 10, 11 and 12 early. Second, our solution for 11 Backwards Compatibility was that our platform team weren’t allowed to release it without fixing any application breakages. That won’t work in general, but for an in-house MDSF for a few systems it does (especially if your CI is set up to help).

  6. Johan den Haan December 3, 2011 | Reply

    Thanks Peter, for sharing your experiences! It’s good to hear you recognize most of the lessons. It would be interesting to compare and share your experiences again once you’ve built version 2 and 3 of your model driven platform!

  7. Glenn August 14, 2012 | Reply

    Like Peter, I am also coming to the end of a MDSD project that generates admin style web apps generating Google Closure on the front end and Java components on the back end. I see a lot of similarity between your advice and my http://www.dynamicalsoftware.com/mdsd/closure 10 lessons learned during that project.

Leave a Reply