Article: Best Practices for Model-Driven Software Development
Read Best Practices for Model-Driven Software Development.
Best practices covered include:
- Separate the generated and manual code from each other
- Don't check-in generated code
- Integrate the generator into the build process
- Use the resources of the target platform
- Generate clean code
- Use the complier
- Talk in Metamodelese
- Develop DSLs iteratively
- Develop model-validation iteratively
- Test the generator using a reference model
- Select suitable technology
- Use textual syntax correctly
- Use Configuration By Exception
- Teamwork loves textual DSLs
- Use model-transformation to reduce complexity
- Generate towards a comprehensive platform
DSLs and code generators can, when used appropriately, be an immensely useful tool. But the focus should always be the problem to be solved. In many cases, it makes sense to describe certain, but not all, aspects using DSLs. Projects which decide from the get-go to follow a model-driven approach are ignoring this last piece of advice.Are you doing MDD? What have been your experiences?
I've seen some tools represent XMI UUIDS as an xpath-like path and uuid. This way they can generate an intelligent error message when the referenced object is missing.
If you are thinking of going down the XMI path and sharing large artifacts with a large team then I would highly recommend stress testing the tools to see what pain they give you. There are lots of gotchas that can cause issues with the development process. For example how will the tool handle language changes and branching and will you effectively lose your version history if you make changes to your language. Don't blindly trust vendor claims.
For some tools the model validation process is very important for preserving the integrity of the model. If the validation process runs so slowly that developers don't run it then you can get some nasty problems. One popular XMI framework proxies cross model references and if the actual reference can't be found when the proxy is interrogated then it will give back incorrect values instead of an error. This can create subtle errors if models are compiled without being validated first.
I also have strong doubts about embedding in another modelling language like UML. One of the advantage of writing your own language from scratch is that you can embed a lot of the rules of the language in the structure of the language. If you are willing to embed in another modelling language then I think you should consider embedding in a programming language. Embedding in a programming language can make development faster because you can harness incremental compilation and quick validation performed by the IDE (though this will often be weak). Situations where you are not heavily using the semantic checking or where interpreting is easy and fast or where you have to write custom code side by side with the model make embedding in a programming language more attractive.
I think the most important thing the MDA community has to realise is that MDA doesn't necessarily mean UML and MDA doesn't necessarily mean graphical diagrams. There seems to be some kind of obsession with UML and programming with pictures.
Sculptor is a good example
In the development of Sculptor we have actually used all of the best practices described in the article, except 'Use graphical syntax correctly' which is not applicable for us.
Sculptor is an Open Source tool that applies the concepts from Domain-Driven Design and Domain Specific Languages.
You express your design intent in a textual specification, from which Sculptor generates high quality Java code and configuration. Sculptor takes care of the technical details, the tedious repetitive work, and let you focus on delivering more business value – and have more fun.
The generated code is based on well-known frameworks, such as Spring Framework, Spring Web Flow, JSF, Eclipse RCP, Hibernate and Java EE.
The DSL and the code generation drives the development and is not a one time shot. It is an iterative process, which can be combined with Test Driven Development and evolutionary design.
Sculptor home: fornax-platform.org/cp/x/aAQ
know your target
That leads to two other observations:
1) be careful when you do your DSL iteratively that you do not have to rewrite your existing DSL instances (i.e. artifacts that are written in your DSL) again and again, when your DSL definition changes too often. DSL instances aren't easily refactored.
2) depending on the stability of your generator, you should really think hard about not checking in the generatted artifacts. Are you sure that your current generator will still work in two years? Do you have archived everything needed, so that it can still run (IDE?, JDK?, Ant?, All needed Jar-Files?, Maven-Repository? ...)?
Don't check in generated code - no always true
Ask yourself: Do this gen-ed code realy changes that often? How much of it do we have? How much time does it take to generate it? Sometimes it will be better to check in the gen-ed code and when needed just regen' it and override the existing version.
Eyal's blog: blogs.microsoft.co.il/blogs/eyal
Re: Don't check in generated code - no always true
When separating along the lines of a core and an application team one should be giving the application team the binary artifacts of the core team build typically in form of libraries.
In most build environments one produces these binaries as a matter of course and does not check them in.
Feedback on new tool ...