Posts tagged “metamodeling”.

Balancing Variability & Commonality

When creating a DSL (Domain Specific Language) one of the most important choices is to decide about what items in your domain are going to be considered variable, changeable and which ones are going to be considered fixed, carved in stone.

The former need to be specified in your DSL, in your design or may be coded. The latter are considered immutable and will remain static for all your derived applications for ages.

Considering that everything is static it is obviously useless. On the contrary, considering every aspect variable drives to another no-end getting nothing tangible again as a result. Therefore, in the middle we will have to search for the virtue.

The main issue here is to study a domain and ponder between variable parts and fixed parts. It is not a trivial thing to do from the very beginning. Experience in DSL construction and specially, experience in the domain helps to train your smell, but there are not clear rules for it, nevertheless.

It is not only about knowing your requirements. It is about trying to predict how your requirements will change across time and what types of requirements have more likelihood and tendency to change.

Adding variability

A variable part could be, for example, the background color of your application. If so, you need to add syntax and semantics to your DSL to capture such property. Let’s say you can express somewhere in your specification:  { background-color = peach; }

We can select the peach color for app1, and may be ivory for app2.

However, nothing is for free and this freedom comes with the followings possible drawbacks:

  • You need to increase the size of your language (DSL), editors, model checkers, compilers and code generation or interpreters.
  • Users have to provide a value for such property unless you have also provided a sensible default value in case of missing information.
  • Homogeneity across applications vanishes with respect to background-color. Now it’s a user choice (the one in control of the modeling tool).
  • Specs are more complex.

Adding commonality

On the other hand, if you consider the background of your application should be always the same because you are following, for example, a user interface style guide then, the background color is a fixed issue. Its value is provided by design by a style guide, by an architect, or design choice and the user modeling has no control over it.

In this scenario, the DSL is smaller. No need to specify the background color, it is implicit, it is no included in the model/specification.

With this kind of choice, we are betting for standardization. A shared library, a runtime framework or an interpreter will take care of supplying the right color in the right moment.

  • Users can not change the background color, specs are smaller.
  • Standardization is improved across applications.
  • User has no control on the feature.

But, what is the right choice?

It depends. There is no right choice with the information given till the moment. To answer the question we need to consider if the background color is a fundamental feature in our domain and it is needed to be different from application to application or may be, on the contrary, the color should be used in an homogeneous way following a predefined style guide.

Again, the domain imposes the rules to follow. Studding the domain and its variability is crucial to create a consistent DSLs focused in gathering the key features of the domain in a model: the important and variable ones. The important and fixed ones must be also identified but they shouldn’t be included into the model, but into the framework or the runtime.

Standards, policy assurance, compliance

Everything related to standard procedures, compliance and in-house stile guidelines are first-class candidates for standardization. If done in that way, your developers will not have to remember all that weird standard and compliance rules when developing a specific artifact.

A code generator will provide the right value for them. It will do it silently, without errors neither oversights. All the boring code dedicated to plumbing applications like: naming guidelines, service publication, serialization, persistence, adapters, proxies, skeletons, stubs, DAO code are driven by strict standards and best practices and are natural candidates for strong automation by code generators.

Moreover, if the regulation or the standard changes, the change will have impact in the following assets:

  • a single change to a framework will be enough
  • or a change to a code generator and then forcing a regeneration process and redeploy.

In both cases, it is cheaper that manually reviewing a set of in-production applications.

For example, think about replacing your data-layer access code from a DAO pattern and SQL to an ORM based approach like Hibernate.

Business Know-How

The core of the business Know-How is the important and the variable parts we are interested in to be collected in a specification. Such features need to be modeled, and if possible, abstracted from the technology that will implement it.

If we do it in this way, the model can survive the current technology.

Why we could be interested in do it in such a way?

Just because technology evolves like fashion. Today everyone likes red T-shirts, tomorrow blue jeans will be sublime! Basic, Cobol, C, Java, C#, Ruby… what is the next language to use in 5 years time?

Use your best bet, whatever platform better fulfills your requirements, but I it could be nice to see the business process surviving the technology. 😉  We don’t know in which direction, but technology will evolve, and will change for sure.

Maintaining a language or a DSL

When a DSL or a language needs a review you will be probably considering adding new features to the language.

Each new feature will increase the variability and increase the complexity of the language. Before deciding to add a new modeling feature make a cost/benefits analysis and double check that the valued added by the improvement is greater than the cost of implementing it.

I like to follow the golden rule proposed by Gordon S. Novak about automatic programming:

“Automatic Programming is defined as the synthesis of a program from a specification. If automatic programming is to be useful, the specification must be smaller and easier to write than the program would be if written in a conventional programming language.”

Conclusion

Whenever is possible:

  • Business Know-How should be captured by models, specs, DSLs.
  • Technical Know-How should be captured by code generators, model interpreters, best practices and patterns.

So, at the end of the day I like the following pair of quotes to sum up about what to include in a model:

  • The Spanish writer Baltasar Gracián in the XVII century said “Lo bueno si breve, dos veces bueno.” (a literal translation from Spanish could be: “Good things if brief, twice good.”)
  • On the other side, Albert Einstein (XX century) counterpoints “Things should be as simple as possible, but not simpler.”

Essential.Meta: A concise DSL for metamodeling

L'umbracle, Valencia, from the Collection: Life on Mars? By iFovea via flickr.com

In my previous post, I introduced Essential, a custom-developed tool for doing Model Driven Development.

As promised, in this post I will describe the primitives of the first language of the tool: Essential.Meta. This meta-language is helpful to describe the structural aspects of a metamodel.

The input requirements for the language are:

  1. Usable for meta-structure description
  2. Human readable/maintainable
  3. Concise as possible
  4. Easy to understand
  5. Object oriented
  6. Technology agnostic
  7. Textual
  8. Extensible
  9. Scalable
  10. Reusable definitions

Ok, that was the initial wish list. Now, let’s review how we can cope with it and show a short example of how it looks like:

namespace Meta.TownModel
{
    enum Sex  {  Male, Female }

    class Town
    {
        string Name;
        List<Person> Habitants;
        composition List<House> Houses;
    }

    class Person
    {
        string Name;
        string? MiddleName;
        string Surname;
        Sex Sex;
        int? Age;
        List<Person> Children;
        House Home;
    }

    class House
    {
        string Address;
        composition List<Room>0..* Rooms opposite 1..1 House;
    }

    class Room
    {
        string Name;
        decimal? Dimensions;   //In square meters
    }
}

The sample describes a meta-model for describing a town, with its buildings (houses) and inhabitants (persons). Nothing complex, nothing weird if assuming I am using a C/C++/Java/C# syntax and this doesn’t suppose a problem for you. I selected a C-like syntax instead a Pascal or VB flavour due to its less verbosity and a probably biased to what we used get to.

The namespace defines a scope for naming. All of our definitions are enclosed in a namespace. Therefore names of concepts should not collide inside a namespace. Same names are allowed in different namespaces.

As you can see, the main concepts in this language are classes and enumerations.

Enumerations define closed sets of named values helpful to describe domains. Classes on the other hand, have the classical meaning and properties or attributes can be defined for each class.

As usual in object languages each property has a type that could be primitive, an enum, a class type or a composed type.

The primitive data types supported are: string, bool, int, long, decimal, char, date, time & datetime. That should be more than enough, for the moment.

A note to readers: data types here are platform neutral, they are not java string for example, neither a C# string. It was horrible for me to see in a lot of diagramming UML tools whose names I will not cite, early mapping types to implementation languages like java:string and similar things… I sure you understand me. Such feature could be nice if you are doing reverse engineering or documenting code (a bit late BTW). But definitely horrible to see when doing conceptual modelling and haven’t chosen yet the final implementation platform.

Another relevant feature of the language is the cardinality operators. Each property has a cardinality attached to it. Following a Convention over Configuration approach, simple properties like string Name; has an implicit cardinality 1..1. You can also write to make it explicit in the language: string 1..1 Name;

List of things, on the contrary has an implicit cardinality of 0..* (zero to many). However you can further constraint it to 1..* (compulsory multi-valued) or arbitrarily to any pair of minimal and maximal values List<Holes> 18..24 GolfCampHoles;

The next feature to review is the composition keyword. A composition indicates that the property can’t exist alone, without its container. If the container is destroyed, the composed children will disappear also. Containment should be unique for each object; it cannot be contained in two direct containers at the same time. However, transitive containment it’s allowed.

There are some times, when we will be interested not only in one side of the relation between two classes, but also in the others’ end. That’s the case of the Children property. How about reaching the parents? To express it, the language introduces the opposite keyword. In our small sample it can be fully expressed (cardinalities included) as:

List<Person>0..* Children opposite 0:2 Parents;

Make sense, isn’t it? A person can have 0 or many children and let’s say zero, one or two well known parents.

I am still considering if the keyword List<T> could be also removed from the language. One can argue that cardinalities can be more than enough to express the same. However, I am still considering including other composed ADTs (abstract data types) in the future like Set<T> or Stack<T> to cite some of them. So, doors are still open to reconsider it.

Another feature we wanted to add is extensibility: If you are using this metamodel but needs to extend it for your own needs, the language is prepared to allow it. Just add another definition like this in another file and you got it:

namespace Meta.TownModel
{
    class Town
    {
        Person Mayor;
    }
    class Person
    {
        List<Person>0..* Friends opposite 0..* Friends;
    }
    class City : Town   //<--Inheritance sample
    {
        //extra city properties…
    }
}

Now, your town must have a mayor and persons can have friends!

The language allows partial definitions in the same or different files. If the namespace and class name matches, the properties of the Town class and Person class are extended by merging partial definitions.

From the cardinality point of view, Friends is a curious symmetric relation. It is a many-to-many relation but both ends  (the roles) are normally called Friends and not: MyFriends and OthersGuysConsideringMeAFriend but how knows! }:)

As briefly seen, this language is useful to impose rules over data. It constrains the objects/concepts we can describe and the allowed properties.

Intended usage

OK. Some of you are probably thinking: and what in hell it this useful for?

The mail goal is to use the language to describe the domain in which we are planning to apply MDD. With this description, we will describe the concepts, properties and relations of the problem domain we are interested in.

If you are really, really pragmatic, and the analysis and design of the domain for the joy of it doesn’t satisfy you, well, consider then that we can derive (manually or better 100% generated if you prefer) some other interesting and more earthly artefacts:

  1. UML class models (structure), XMI, etc.
  2. XML Schema (XSD),
  3. SQL Schema (relational tables to persist the data),
  4. Classes in Java (POJOs), C# (POCOs), or any other language implementing a pure Domain Model
  5. XML de/serialization code to read/save XML documents been conformant with (2)
  6. Data Access code (DAO) to connect (3) with (4).
  7. Maps to your favorite ORM tool to connect again (3) & (4)
  8. Etcetera, see Domain Driven Design and other approaches.

That’s all for today! This was the first DSL implemented in Essential targeting metamodeling. For more details, a full reference of the Essential.Meta language is described here.

On the next post, we will talk about a second DSL in Essential: the model (object level) language used to instantiate the concepts we just have created.

Thanks for reading! And please share your thoughts about it!