In this article, we're going to take a look at a development process using the technique of "Model-Driven" development. The example of this process we use utilizes the Keel meta-framework as a component toolkit and service provider, and shows how several different model projects can be used in conjunction with it.
Keel was built to provide a connector between multiple frameworks, and to provide a ready-made server side infrastructure for the development of Java applications. Although it emphasizes Web applications, Keel can be (and has been) used for desktop application development as well. This makes it a good basis for our example because we don't restrict ourselves to any one deployment environment. Keel also features a number of services that are a "good fit" with the technique of model-driven development, making our example easier to follow.
What Is Model-Driven Development?
Like many terms, there is some debate about what Model-Driven Development entails precisely, but if we take the most generic meaning, most developers agree: Model-driven development is a style of software development that revolves around a "model," or more precisely, a meta-data definition of the application. Often, model-driven development will entail diagrams, perhaps in UML, that in turn form the basis of the application model or meta-data. Depending on the tool being used, the development cycle then either begins with or involves code generation, whereby tools are used to prepare the initial Java code. In more advanced model-driven tools, manually edited code can even be re-generated (while losing none of the manual edits), to keep it synchronized with later changes in the model.
What distinguishes model-driven development from "regular" development is that a set of "meta-data" (the model) exists, and that the development process proceeds from this model. Exactly what the model consists of, and how it's used, varies somewhat from tool to tool, as we will see. The goal is to make application development faster and easier, removing a lot of the tedious and repetitive work, and hopefully at the same time reducing many common errors, while also helping to ensure that the design of the application is accurately represented in the finished code.
Model-driven development is actually somewhat related to the older concept of CASE (Computer-Aided Software Engineering), but where CASE could, and often did, apply to the entire development process, model-driven development usually applies only to the translation of a design into code, and the corresponding code generation.
Today, there are a substantial number of tools for enabling model-driven development, both commercial and open-source. Some of the commercial tools go all the way from visual UML diagrams to IDE and the reverse—updating the UML based on changes to the source code. We'll briefly examine a couple of the more popular open source tools to get a feel for the process.
Argo/UML and Poseidon
Many projects begin by using a UML diagramming tool to outline the structure of the system to be developed. One of the most popular open source tools for UML design is Argo/UML. This is a full GUI desktop application that allows creation of virtually the entire set of UML diagrams, with the ability to save those diagrams in the XMI format, which many modeling tools use as their source for code generation. A commercial extension of Argo/UML is also available, Poseidon from Gentleware (http://www.gentleware.com/), for organizations that want additional features or professional support. There is also a free community edition of Poseidon.
Once we have modeled our application in Argo or Poseidon, we move on to the actual generating tools.
The Eclipse Modeling Framework (EMF) project is a toolset that brings modeling functionality to the popular Eclipse platform and IDE. It allows a model to be created in one of several forms (including UML diagrams from a number of popular diagramming tools), and convert them into an XML representation of the application, called Ecore. This Ecore model then can be used to generate Java code with embedded XDoclet-style tags (for an introduction to XDoclet, see the XDoclet site at http://xdoclet.sourceforge.net/). The generated code then can be edited as usual. If (or, more realistically, when) the model changes, generate can be re-run without overwriting any custom code; only code identified with the special tags will be updated, allowing custom code to be created without having to "freeze" the model at any given point.
EMF's default mechanism is to generate code for an interface pattern—that is, an interface describing the functionality being developed, and a separate implementation class that contains the specific functionality. This is a good fit with the Keel meta-framework because it (and the underlying Avalon framework) uses exactly this approach for all of its services. This makes it easy to model a new Keel service with EMF, generate the interface and skeleton implementation, and then fill in the implementation class with the actual code to render the service.
EMF is well documented (there's an entire book about it, in fact) and highly extensible. Its API makes producing sophisticated custom generating capabilities possible, and its tight integration with the Eclipse IDE bring all elements of development together in a single tool. When used with a UML Eclipse plugin, for example (there are several available), EMF allows you to go from modeling to coding and back—all from within Eclipse.
Another choice of open source project for model-driven development is AndroMDA. AndroMDA is not integrated with an IDE, but can be used with any project that utilizes "Ant." By default, it includes a number of "cartridges" (plugins for specific capabilities) that can generate code for both EJB and non-EJB environments from a UML model file in XMI format—just like the files that Argo/UML writes out.
To apply AndroMDA to our example, using Keel, we can immediately generate code from a UML design for JDO classes, using one of Keel's JDO implementations. For application logic classes (called "Model" classes in Keel), we would probably want to customize one of the existing cartridges and templates (likely starting from the one that generates Struts Action classes), changing the way they produce code to comply with the Model interface.
With very little effort, then, we find ourselves with a powerful tool for turning UML diagrams directly into skeleton Keel applications, both persistence and application logic. The classes themselves contain generated XDoclet tags that produce the appropriate configuration. In practice, very little "by hand" adjustment is required to get a basic application up and running with this method.