MDA From a Developer's Perspective

Java Development News:

MDA From a Developer's Perspective

By Stefan Tilkov

01 Dec 2002 | TheServerSide.com

You've probably heard about Model Driven Architecture (MDA), the Object Management Group's brand-new approach to software development. It's likely you have also seen lots of product announcements, where new "MDA tools" appear in the market and existing ones, such as CASE tools or IDEs, suddenly become "MDA enabled". In this article I'll try to explain what MDA is all about, and do so in a bottom-up way. By this I mean that I'm going to focus on the benefits a developer (as opposed to a manager or someone with architectural responsibility in an enterprise) can gain from applying an MDA approach.

One thing that never ceases to surprise me is the way some developers are willing to implement the same thing over and over again. I'm not talking about writing a software system for the third of fourth time, each time applying experience and lessons learned from the last iteration. That's perfectly fine with me, and in fact I believe that most good software is based on something that has been thrown away at least once. What I'm talking about is doing the same thing again and again on a different level. Think, for example, about the patterns you apply when you develop a J2EE system. If you're following decent architectural guidelines, you might define operations in your EJBs to take value objects as parameters. These value objects are simple, plain old data types that hold some state. Typically, each of those attributes has a read and a write accessor, and perhaps also something like "isNull" to check for null values:



public class ExampleValueObject {
  private long value;
  private boolean valueNull;

  public boolean isValueNull() {
    return valueNull;
  }

  public long getValue() {
    return value;
  }

  public void setValue(long value) {
    this.value = value;
  }
}


(I'm not surprising anyone yet, I know. Please bear with me for a few seconds more.) Chances are you have implemented this pattern, probably better called an idiom, about a thousand times at least. If you're like me, you hate doing things that can be automated by hand, so you are likely using some sort of IDE like JBuilder, Eclipse, IDEA, or even Emacs, all of which allow you to automatically generate accessor methods for attributes. (Thinking about it - how many IDEs do you know that allow you to generate not only the bean-like get and set methods, but an isNull method as well?). This is a very simple case, but if you consider it for a while, you'll find that your code is full of patterns like these, from very simple to very complicated. Some examples of patterns are:

  • classes used for communicating with servers remotely;
  • the combination of classes, interfaces, and deployment descriptors used to describe and implement how you persist objects using J2EE CMP;
  • classes implementing alternative persistence strategies, such as session beans managing simple Java objects in combination with a persistence layer
  • Java Beans used to allow for communication between the web tier and the EJB tier;
  • and lots more.

If you look at all those occurrences, you'll notice that in most of these cases, a very simple structure is behind all of those implementation details, together with a specific mapping of those structures to an underlying platform.

Let me elaborate on that a bit. Assume that you have a simple object model, described in a UML class diagram:



Figure 1

If you are using a pre-EJB 2.0 application server, you might have made the decision to use BMP entity beans only and persist objects using some sort of DAO pattern. For each persistent object, you decide whether it's worth being implemented as a bean or an object only, following what used to be called a "coarse grained object pattern". Regardless of whether you're using UML or not, the result you get when you implement your object model following those rules might look like this:




Figure 2


So where is this leading us? Imagine that you introduce a few new attributes to your customer object. You will have to make modifications to the customer bean's remote interface because of the new getters and setters (or, if you're following a value object pattern, to the value object associated with it); you'll need to apply the same change to your DAO, as well as to any other class somehow affected by that change. Adding an attribute is not what I would term a complex change. So why would I have to edit 3-5 different files for a change as simple as that?

Now think about what happens when you switch application servers, or even upgrade your app server to a new version. Let's say it supports EJB 2.0, including CMP, and it does so very efficiently. Let's also assume that you want to take advantage from that fact, resulting in a model that might roughly look like this:



Figure 3


Where does that leave you? It's not your logical object model that changes. A customer is still associated with an order in the same way as before. It's the rules, the mapping from logical to physical model that change, forcing you to touch each and every single software artefact related to persistence. Do you really think it's worth your time doing that? Do you call that creative work?

Of course, a real-world architecture will be a lot more complicated. The same principles apply, though. After all, what is architecture if not a set of rules stating how to solve common problems?

So what's the point? You'll remember that I started by describing that I wanted to explain MDA bottom-up, and hopefully I have convinced you by now of some facts:

  1. When you implement a solution on a powerful platform such as J2EE, you follow certain rules to map your logical model to a physical representation.
  2. If this transformation could be automated, you'll be able to save a lot of time required for tedious, uncreative work.
  3. Separating a logical model from a technical mapping will isolate changes made to the two from each other.

So let me now step a bit more into MDA terminology and explain what the OMG suggests as a solution.

First of all, the OMG introduces the concept of platform independent and platform specific models (abbreviated as PIM and PSM, respectively). An example of a platform independent model is the one given in Figure 1 (although one might argue whether this is really platform independent, but more on that later). The idea is to have a model that represents business knowledge without being cluttered with technical detail. Figure 2 and Figure 3 clearly represent platform specific models, being tightly coupled to the underlying platform. When using MDA, PIMs are transformed into PSMs by applying a mapping or transformation. PIMs and PSMs can exist on different levels; basically, your PIM might be somebody else's PSM, depending on their perspective. Thus, a transformation might include several steps, from highly independent to more and more specific ones. The final result of the transformation will (hopefully) be the code. In my view, the code is also a model - but your mileage may vary here.

To put it very simply, MDA is thus exactly concerned with solving the problems mentioned above by allowing you to look at and modify your logical model (the PIM) independently from the underlying platform, automate the transformation into a PSM, and thus be able to change the two of them independently of each other.

To do this, MDA relies on some technologies that are controlled by the OMG, but are pretty much ubiquitous:


UML - the Unified Modeling Language

Probably everybody knows UML, so I'll not go into too much detail here. UML has become the one and only wide-spread standard modeling language, so that if anybody uses a modeling tool or simply draws something on a whiteboard, it'll most likely follow UML conventions. UML defines a lot of different diagram types, the best-known of which are the class diagram and the interaction diagram.


XMI - XML Metadata Interchange

XMI is a standard, XML-based language to exchange model information between tools. All of the leading CASE tools, such as Rose, Together, Innovator, ArgoUML, Enterprise Architect and so on support XMI as their standard import and export format. XMI is not as standard as one could hope, but it's getting there.


MOF - the Meta-Object Facility

This is probably the least known of the OMG standards, although I personally consider it to be the most important one. MOF is a conceptual framework for describing meta-data. Meta-data is, as the names suggests, data about data. To explain this, consider the following layers:

0. A customer, ACME Corp., has placed an order for 32 boxes of candy on the 23rd of April.
1. A customer has a name and can place zero to n orders, each order having a date and referencing a specfic item that is being sold.
2. Classes have attributes which have a type, and classes can be related to each other.
3. There are things that describe something, and there are connections between those things.

With numbers increasing, we move away from pure information (level 0) to a model layer (1), to a meta-model layer roughly resembling UML (2), to a meta-meta-model layer representing a way to describe meta-models.

MOF is mainly concerned with level 3, for which it contains a hard-coded set of "things". (If you're not confused enough already: in fact this layer is a subset of UML. Don't worry, things will hopefully become clearer soon).

So what is MOF? MOF is way to describe meta-models, which in turn describe a specific way to model something. One example of a well-known meta-model is UML. But the separation allows MOF to be independent of UML and support other meta-models as well. MOF is thus a very generic and very powerful framework for expressing model and meta data information.

Apart from being a conceptual framework, MOF also defines a CORBA IDL mapping that specifies how MOF data can be accessed from CORBA applications. With JMI, the Java Metadata Interface, the JCP has just finalized a mapping of these interfaces for the Java language.


XMI - again

Huh? Didn't we already discuss XMI? Yes, we did - but as we now know what MOF is about, we'll have to take a closer look. In fact, XMI cannot only be used as an interchange format for UML, but for any model that can be described by a MOF meta-model.

Let me give you an example. Let's say that your organisation defines a meta-model to express certain concepts, for example the concept of a business service. Each business service might be an aggregation of interfaces, each of them consisting of operation signatures. Each business service might also have an owner and a version it is available in.

MOF-compliant tools would allow you to define this meta-model, import it into e.g. repositories and CASE tools, and start drawing or editing model information - i.e., concrete instances of business services. This model information could then be exchanged with other MOF-compliant tools via XMI.

An existing example of a MOF-compliant meta-model apart from UML is the Common Warehouse Meta-model, CWM, which is defined by OMG and used to describe meta-data for use in data warehousing scenarios. It includes well-known model elements such as tables, columns, views, and indices.


Back to the beginning ...

So how does all of this relate? MDA is just starting to become popular, and while user-defined meta-models will definitely become, IMHO, extremely popular in the future, for now they are concerned mainly with automating the transformation mentioned quite a few times.

So what type of tools should you take a look at? There are quite a few MDA-compliant software generators out there, one of them being iQgen (iQgen is freely downloadable at http://iqgen.innoq.org), the one the company I happen to work for produces. iQgen is able to read a logical model, a PIM, in the form of an XMI file as exported from a CASE tool. These PIM is then transformed into the ultimate PSM, the code, based on a set of rules defined as templates.

The issue of transformation is the one the least specified by the OMG at the moment. Therefore, available tools use different strategies. iQgen uses Java Server Pages, which allows Java developers to start developing templates (or rather, refactor existing code into templates) without having to learn something new. Other tools rely e.g. on Jython or Jakarta's Velocity template engine. All of them preserve code that has already been modified, usually by enclosing it in some form of special comment.

All of these tools enable you to code with different perspectives. While you make structural changes in a UML model, you define the transformation or mapping to your selected software architecture in a different, localized place. Moving from e.g. EJB 1.1 to EJB 2.0 (or the upcoming 2.1, for that matter), is simply done by changing templates. This dramatically reduces monkey-work, saves a lot of development time, and enforces adherence to architectural principles in your application.

For the future I expect three major things to emerge:

  1. CASE tools will become MOF-compliant. This will allow users to define their own meta-models, import them into the CASE tool, and start drawing diagrams conforming to them.
  2. CASE tool vendors will have to shift their focus from documentation to efficient maintenance of model information.
  3. "Real" model-to-model transformation, based on MOF, JMI, and the result of the MOF 2.0 Query/View/Transf. RFP issued by OMG, will become commonplace, pushing programming tasks to another meta-level.

But that's just an expectation of what might become mainstream in the future. To stick with the goal of introducing things in a bottom-up approach, I'll also try to address some of the concerns people have about automating software development, and about code generation in particular. When you talk to people about the use of code generation, as I very often do, you will immediately be confronted by either great enthusiasm or equally great skepticism. There are, of course, valid points that can be made against using a generative approach. But in my experience, I have found that most of these only apply to specific products, can be circumvented easily, or are based on a plain misunderstanding of the way the technology can and should be used.

In the following paragraphs, I will try to list some of the most common reasons against code generation, as well as describe how they can be addressed.


10 Myths About Code Generation

1. Code generation is a great way to impress managers, but once you hit the 80% wall, you need 800% more effort to achieve the final result.

This is very true for tools that force you to accept what they deem to be "the right way" to build your software. It's also the reason why a lot of people don't like to work with 4GL tools like PowerBuilder. Basically, you get a lot of benefits from the fact that they hide the complexity, but you run into severe trouble once you need to solve a problem the tool designers did not expect.

A good tool will enable you to automate what you would otherwise do by hand. The code generated should be - at least in principle -no different from what you would have written yourself. It's also of critical importance that you can still implement things without using the generator, because for some things, you need to be able to put the full power and flexibility of the underlying platform to use.

If your tool environment enables you to use code generation where appropriate and mix the result with hand-written code as needed, you will get the best of both worlds.


2. People will soon start to modify the generated sources, making repetitive generation impossible. So why bother?

A one-shot code generation approach, i.e. one where you generate an initial skeleton implementation and then do the elaboration by hand without being able to regenerate, is of no use at all. This approach reminds me of the first "wizards" that became available in popular IDEs some time ago. So you really need the ability to generate code, enhance it, and regenerate after you have made changes to the model.

But if people start modifying the generated code and break the rules, e.g. by inserting code outside of "protected sections", you will have a problem. I believe that there are two ways to circumvent this:

One is the brute force way that you can apply in certain environments. With this approach, you include the code generation step in your daily or weekly builds by checking out the model and the code and regenerating before you compile. Anything that does not survive this project is not included in the build result, and this is likely to make people break the code generation rules only once. While effective, this approach smells of centralized control, and thus I don't really like it.

The far better way is to use tools that provide a clear and measurable benefit to the developer, so that they will not even think about not using them. Which approach is better depends on your environment.


3. Code will never be generated in a way that meets my standards, coding conventions, works with my architecture and frameworks, etc.

True for a lot of environments, and a very good reason against using them. I am strongly opposed to any tool vendor trying to force their view of doing software development "the right way" on me. Fortunately, a lot of tools in the MDA market allow you to adapt the way they transform and generate code to your own needs. From simple things like allowing you to decide where to put your curly braces, to naming conventions, attribute access, copyright notices, and persistence strategies - everything must be customizable by the end user. And it is - at least in tools that I consider being worth their money.


4. Code generation creates too much of a dependency on proprietary tools.

This is probably the strongest argument one can make as long as MDA standards are still weak. While using XMI as the language to describe your model in should make you independent of any particular CASE tool vendor, it's not as strict as one would like. Every XMI export is a little bit different, so support for multiple CASE tools is a crucial factor in assuring that you can switch to another one, if need be. JMI, the Java Metadata Interface, standardizes the access to model information. In most tools, the way to describe transformations is proprietary, although languages used in specifying templates can include open standards like JSP or Jython. This will hopefully change once the RFP ... is finalized and implementations emerge. At the moment, though, some dependence on a tool implementation will exist in all solutions I am aware of.


5. Code generation has been tried in the past - and failed.

True. Lots of concepts have been tried in the past, and failed miserably. I do believe that with the current hype surrounding the MDA approach, lots of tools appear in the market, which creates a lot of competition, which fuels innovation ... you get the picture. With standard formats like XMI and the rising need for improving productivity, things look a lot different today than they did only a year ago. Don't let past experience make you believe that things can't improve.


6. My CASE tool already has a code generator that I've tried without being impressed.

I believe this is due to the fact that historically, code generation has been added to CASE tools as an afterthought, and I often have the impression that it has mostly been tested during presentation where the main goal was to impress management. Most CASE tools' code generators are very hard to modify, written in some proprietary language (or even Visual Basic, which some might consider even worse), and perform very badly. One should not assume from experience with bad implementations that the scenario itself is flawed - it's more productive to look for a tool that does the job better.


7. I'll just use XML/XSLT and be done with it.

XML and XSL(T) are fine tools, and I use them quite a lot. For example, our product's web site is based on the excellent Cocoon framework, which does a great job of coordinating and integrating transformation pipelines.

There are quite a lot of problems with using XSLT for code generation, though. The most obvious one is that preserving existing code requires quite a bit of effort, e.g. by writing a custom merger task and integrating it with the XSLT engine. When XMI is used as the input format, stylesheets become extremely complicated - because XMI is really, really hard to read and understand. Finally, not everyone knows how to use XSL, and even developers used to it tend to get into problems once stylesheets become complicated.


8. I don't need a code generator, I'm using XDoclet.

XDoclet is cool, and I think that in a lot of cases it's a sensible alternative to a full-fledged MDA approach. If you're still writing (and updating!) deployment descriptors by hand, XDoclet will definitely reduce the work you have to do tremendously. The one problem I have with it is that the basis for all of the automatic code generation is the Java code, which is nothing I can show to my customers. While Java code is arguably an easy means of communication between Java developers, it's probably rather hard to discuss an entity/relationship model with your local DB admin, or the implementation of a use case with a business analyst.


9. It's faster to code something in Java than to draw diagrams in some GUI tool.

If this is the case, by all means use Java. I'm not advocating to do everything with the graphical representation. In my experience, what works best is to make structural designs (and updates to them) in the CASE tool, and implement the generated methods in the code. It's true though that a lot of CASE tools don't easily allow the developer to e.g. create a bunch of attributes efficiently. I think this is something where CASE tools yet have to match the support offered by IDEs. Once they do so, the main argument against their usage - which is again tied to the implementation, not the general concept - disappears.


10. If I use code generation to automate my work, I'll soon be out of a job.

You can easily use that as a justification to program in Assembler. I tend to believe that developers like to be creative, so people justifying their role by doing lots of monkey-work by hand is something I am rarely confronted with.


Conclusion

So what's so great about MDA? If you think that there's nothing so new about it, I'll agree whole-heartedly. MDA is not a new invention; it is a bunch of techniques integrated under a single name. What's good news is that this leads to standards that are supported by different vendors, which is in general considered to be a good thing. MDA is thus an approach that is intended to solve problems common to application development in a standard way, freeing developers and architects from restrictions imposed on them by the complexity of today's technologies.

It's a lot easier to talk about MDA in more abstract terms to managers than it is to convince developers actually implementing systems on a day-to-day basis. In this article, I have tried to point out MDA's benefits from a developer's perspective. Whether I did so successfully is up to you to decide.


About the Author

Stefan Tilkov (stefan.tilkov@innoq.com) is CEO and Co-Founder of innoQ, a Germany-based consulting company focusing on software architecture for mission-critical systems. innoQ provides an MDA-compliant software generator, iQgen, that uses XMI for model input, JSPs as the template language and can generate any text-based software artefact.

Related Resources