Monday, May 08, 2006

Don't Generate Code - Generate Model Implementations Instead

There has been lots of confusions regarding my views on automated code generation, since I wrote my last post. I guess it is the following rumbling that spread across the bad word and insinuated me as one of the crusadors of tool based code generation:
I have never been a fan of automatic code generators, which always tend to produce tons of boilerplates, which could otherwise be refactored much more elegantly using OO frameworks.

To some extent, the lack of expressiveness of my intent has been responsible for this - possibly my ardent readers have missed out the last segment of the above statement which qualifies my disliking to only those code generators which produce tons of boilerplate codes violating the ageold principles of abstraction and encapsulation. That was exactly my point in the last post, where the DAO generator generated lots of Java code which could otherwise be abstracted in an OO framework.

In today's world code generators have a significant role to play in the areas of Model Driven Architecture (MDA). Until recent times, UML had acquired the ignominy of being the unfriendly companion to the project manager - to the extent that we had started talking about Death by UML Fever, where designers produced tons of model documents which became obsolete even before the developers could install the proper plugins of Eclipse. UML 2.0 promises support for MDA - the new MDA-based features allow creation of various architectural modeling styles supporting reusable design patterns.

EMF, the Eclipse Modeling Framework offers MDA capabilities with UML as one of the importers of the model. The model which you design using UML can be directly imported into EMF and Java code for the implementation can be generated directly out of it. The model can be as rich with all sorts of relationships like aggregation, composition, inheritance and association - the EMF code generation module takes care of every iota of the richness and generates Java code as the implementation. Apart from UML, EMF also supports XMI documents, XML Schema and annotated Java as source of model artifact. e.g. We can define an annotated Java interface as follows:

/**
 * @model
 */
public interface Book {
  /**
   * @model
   */
  String getTitle();

  /**
   * @model
   */
  int getPages();
}


EMF code generator will spit out the following as implementation of the above model, a Java interface along with the corresponding implementation class:

public interface Book extends EObject {
  String getTitle();
  void setTitle(String value);

  int getPages();
  void setPages(int value);
}

public class BookImpl extends EObjectImpl implements Book {
  ...
  protected static final int PAGES_EDEFAULT = 0;
  protected int pages = PAGES_EDEFAULT;

  public int getPages() {
    return pages;
  }

  public void setPages(int newPages) {
    int oldPages = pages;
    pages = newPages;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, ..., oldPages, pages));
  }

  ...
}

In the above code fragment (adopted from this series in developerWorks), the generator takes care of complicated semantics like enabling the observer pattern for the set method by notifying any observers of the abstraction through the eNotify() method. Also note the optimization guards implemented by the call to eNotificationRequired(), which, in the degenerate case (no observers) amounts to nothing more than an efficient null pointer check, which is inlined when using a JIT compiler.

The code generator component of EMF, called EMF Codegen, also supports customizable code generation through JSP like templates, JET(Java Emitter Templates) and easy regeneration and merging.

How is the code generator of EMF different from the run of the mill ones which generate boilerplates ?

The heart of the EMF is the ECore Metamodel, which has mapping for every UML construct. Hence when the UML model is translated into Java code, we have a lossless translation which preserves all the richness of the original artifact. An excellent illustration of these capabilities has recently been discussed in a TSS article by Patrik Nordwall. Hence EMF Codegen generates model implementations, as opposed to boilerplates.

So, next time when you think about rolling out your code generator, double check if you are producing code that can be better abstracted through an OO framework. And use your framework model and a lightweight DSL to generate model implementations, rather than boilerplates.

2 comments:

Evan said...

interesting.

Anonymous said...

Very nice introduction to Model Driven Engineering for people reluctant to Model Driven approaches and code generation!