The anatomy of a pattern (part 3)

Odoo • Image and Text

In part 1 we established the need and the goals for a Model-Driven Development approach. In part 2 we formalized the definition of a Pattern.

In this last article of the series, we discuss how we can go about implementing Patterns into a Model-Driven Development platform.

Implementation

So, how to you represent your Pattern?

It’s your team’s choice. XML, drawings, a Domain Specific Language (DSL). The important thing is that the representation is clear, easy to distinguish from other Patterns, its variable options are correctly identified in scope and validation. In Genio we do it in a database. Our model represents information systems so we model the Patterns as tables and fields.

The semantics are the most important part. For now solve the easier part, that is to document and publish the meaning associated with that pattern. We will get back to how to solve the hard part in a bit.

Storage is easy. DSL’s are code files, XML is also just text files, a database can help you make your model query-able and make object dependencies explicit, Diagrams allow you to visualize and have a quick fish eye view. Use one or use them all. But do make sure you treat your model like you treated your old source code, because the model is now your source code. It’s no longer a boring requirements document. The model is the active part of your project. It’s not the dress, it’s the body.

Providing an interface for your model could be considered optional in a MDD platform, but as an engineer, its really not optional at all. Where are you going to enforce model coherence? At the end? That violates a basic principle in software development. Fail early and fail fast. An interface can warn the user to incoherences as soon as he makes them, or even better, not even let him create them in the first place. Code you interface in tandem with your model. Because we use Genio to create Genio, that is what we do, we model and interface the model using itself.

 

Figure 1: Genio treats its models as if they are information to be managed, solving the modeling and interface problems.
Figure 2: Then it saves the model into a relational database, allowing for a standard CRUD API and enabling queries to the model.


Once you have the model, you now want to establish the Artifacts. The thing that your developers used to do over and over again. The good news is: by definition, you already have that. In fact, you likely have multiple versions of it. Some better, some worse, some with better comments, some with faster code. Pick the best one, or merge them into a better version. The bad news is, your work is not finished.

Now you need to implement the “intelligent” part of your MDD platform. You need to turn models into actual working code that actually does what it’s intended to do, according to the variables of the model and according to the semantics you established. You need an engine that iterates your model and you need to adapt your artifacts so they can be completed by the engine. In Genio we do this with code templates programmed in NVelocity and then we have them pull the necessary information from the model through method calls and string transformations.

Figure 3: Example of a Genio template, where the static part of the code is mixed with transformation and model instances.

And there you have it, your solution. Just as if it was programmed by hand. But now its repeatable ad aeternum, no copy-paste bugs, no code quality variance, no time teaching new developers how it’s done right. Of course, this takes work, and I am skipping most of the boilerplate of generalizing templates and extending the generation engine with needed transformation methods. However, the process steps are complete, and I would urge you to start developing them now rather than later. Or, if it fits your development, adopt an already existing MDD platform.

Just one more thing. Remember the semantics? We said that in MDD the semantics are closed. But semantics represents meaning, and meaning is prone to interpretation. How do we close it? Well, we close it by making the Pattern "work", if your working code does what the semantics say it's supposed to do, then they are validated. Generating your code from the model ensures the model is correctly encoding the semantics you imbued it with.

Your working application provides for the model the same double-check system that unit tests provide for functions. If they differ, either the model is ill-defined, or the result is ill generated. When you evolve one, you evolve the other in tandem.

Conclusion

In this series we showed the motivation and criteria for the adoption of a MDD strategy, then defined a Pattern as a set of [Model, Semantics, Interface, Persistence, Artifacts, Automation] that ensures that your generalization of a repeated development task is complete in terms of day to day use and is closed in term of meaning among your developers. Finally, we showed one possible implementation of these concepts into a MDD platform where you can collect your development Patterns and becomes your living technological knowledge base.

Normalizing code quality, automating repetitive tasks, on-boarding new developers, ensuring continuous improvement are not easy things to do in classic software development, but in Model-Driven Development they are built right into the bones of the framework.

So, next time you hear about a Pattern in the context of MDD, this is what we mean.