The following article introduces an XML based approach to Model Driven Engineering, and discusses the benefits of modeling and code generation, and the advantages of using XML technologies for that, such as the wide adoption of XML technologies, cost-effectiveness, flexibility and extensibility, ease of collaboration, and compatibility with the OMG standards.
The article also illustrates some basic examples of XML models, and then discusses a case study of successful applications of this approach to several large-scale software systems.
Traditionally, software designers and architects have been using models to represent certain essential aspects of the systems being built while leaving out details that are irrelevant to these key aspects. Such models tend to greatly facilitate communication between various project stakeholders, and help validating the design or architecture and discovering potential issues in the early stages of the development.
With Model-Driven Engineering (MDE), which is sometimes also referred to as Model-Driven Development (MDD), these models become integral artifacts of the software, and are often used to generate other development artifacts, or are being used directly by other pieces of the software.
With software systems, models generally describe either dynamic behavior or a static structure of the system being modeled.
The models describing dynamic behavior can be applied in a whole gamut of ways from generation of 3GL code that would be part of the system to the actual interpretation of the model by the system run-time, which in fact could even blur the difference between a model and a special purpose scripting language. The latter makes more sense when the problem domain can be well defined by a domain specific language (DSL), which is what the model would be typically expressed in. Certain models may also be describing business rules that are too dynamic to be defined during design time, and therefore can be updated in run-time by a business analyst or an end-user.
On the other hand, the models describing a static structure of the system lend themselves to be used for code generation in a high-level language like Java, C#, or C++, that could be then manually enhanced by developers to build a complete system.
Admittedly, code generation can result in significant increase in developer productivity as it saves them from writing the plumbing code that implements the model, and instead allows focusing on the key aspects of the system that is represented by that model. In addition, it may provide a much higher quality product since the generated code would likely have much less errors than manually written plumbing code. This is not to mention substantial savings in product maintenance and enhancements due to the clearly defined models and ability to quickly incorporate any changes to the model into the product.
Some code generators produce just stubs that developers can modify to build the system, similar to a wizard in an IDE. While this approach may still provide significant savings during initial development, it could be of limited value if the generated code can not be regenerated at a later point. Generally, to enable regeneration, developers should not touch the generated code, but rather extend, customize, or override it separately. In most object oriented languages, this can be achieved by inheriting from the generated class and adding or overriding functionality as appropriate. Some generated artifacts though may not be easily customized without updating the generated code. For example, it could be pretty tricky to allow editing generated rich client forms or server-side web pages with standard IDE designers and yet keep the generated code intact.
So far, there have been a lot of proprietary formats for defining models, model transformations, and code generation. Some work has been done by the OMG group to standardize the modeling language (UML) and to define a framework for model transformations as part of the Model Driven Architecture™ (MDA) initiative.
While OMG specifications have been implemented by a number of vendors, using XML for defining models and transformations presents a very powerful and inexpensive alternative. Here are the key benefits of using XML for modeling:
- XML is a much wider industry standard with abundance of various tools and technologies built around it. As an industry standard, it can make it much easier to find the right resources for building models and transformations that have experience with XML technologies, than to find experts that are familiar with the OMG specifications and the vendor specific tools.
- Models defined in XML are much more flexible and extensible than the models built on the standards, since in order to enhance your model in a non-standard way, you may have to wait till the standards are enhanced and adopted by your vendor first.
- So long as XML is stored in a plain text format, your models can be easily stored in a standard version control system like Subversion or CVS that would allow multiple developers to work on a model simultaneously and then view and merge the differences like with any other text file. You would not have to purchase any special expensive version control systems for your models like the ones used for storing UML diagrams.
- In order to define your meta-model (i.e., a grammar for models), you can use the standard XML schema definition language (XSD), which may not only allow you validating your models but can also help you build your models by prompting the allowed values as you edit the XML.
- For model transformations and code generation, you can obviously use the powerful XSLT technology that has many vendor implementations, including free ones.
- And finally, your models can always be made compatible with the OMG standards by creating a transformation to the XML metadata interchange format (XMI) that is used by UML.
Object Model in XML
Let’s consider an example of a business object model that is defined in XML. The main purpose of such a model would be to describe the system’s business objects and their operations in just one place and get the business object representations generated for each layer of the system. In a typical multi-tier system that consists of a database (DB), business layer (BL), and some user interface (UI), a single field of a business object can be represented by as many as six times in various layers such as the following:
- A database column;
- Parameter of a Stored Procedure used to update the DB column;
- A field of a business layer object;
- A field on value objects used for communication between the UI and the business layer;
- A property on a UI data object that is used as a data model for the UI forms;
- A user interface control that is bound to this field.
In other words, a seemingly simple operation of adding a new field to a business object or changing an existing field could result in a chain of changes across all layers, that could take a significant amount of work. In addition, developers need to make sure that the types and sizes for this field are consistent across all layers.
In order to address this issue, we will describe all the necessary types and business objects in an XML model that will be used to generate representations of these business objects for each layer of the system.
Each type defined in the XML model will have a name, size, and a base type that it extends from, so that we could effectively define a type hierarchy in our model. Additionally, each type may specify the physical type in each layer that it maps to. If any attribute is not specified on a given type, the one from the base type will be used. As a result, our type definition could look like the following:
<type name="phone number" size="15" base="string">
After we define the types in our model, we can start describing business objects and their operations that would be referencing these types. As a simple example, we can describe a customer object that has several fields and a read operation to retrieve these fields, as follows:
<field name="customer id" type="number" key="true"/>
<field name="first name" type="name"/>
<field name="last name" type="name"/>
<field name="home phone" type="phone number"/>
<field name="cell phone" type="phone number"/>
<field name="fax" type="phone number"/>
<arg name="customer id"/>
<arg name="first name"/>
<arg name="last name"/>
<arg name="home phone"/>
<arg name="cell phone"/>
An object description like this alone contains enough information to enable generating a database table, Stored Procedures to update it, and all the necessary objects in the business layer and on the user interface side including a method for reading the object from the business layer.
Obviously, the complexity of the generators will largely depend on the power of the frameworks used by the generated objects. If no frameworks are used, then the generated classes will have to implement all the standard plumbing on their own, which would require building a lot of code into the generators that could make it very hard to debug it. On the other hand, if the generated classes are using a powerful framework that implements and supports all the necessary plumbing, then the generators could be very easy to write to the point where they would merely make the generated objects subclass the right base class and just declare or add the fields of the right type. Since a framework like this may be pretty tricky to build, the code generators will generally wind up somewhere in between of the two approaches.
As I have already said, the best thing about defining a custom model like this in XML is that you can easily add any enhancement to it to supercharge your model and the generators and to allow customizing the output. This could make it possible to retrofit your existing objects to use the new model and take advantage of the code generators, which would slash down the maintenance costs for that code.
Object model is not the only one that can be effectively defined in XML. For example, you can also define your security model in XML with all roles and privileges, which could be used either directly by the code or to generate a SQL script for loading security data into the database. Additionally, it makes sense to generate the code for accessing security model from within the user interface and business layer code, so that when the XML model changes, compilers can catch the places in code that have not been updated accordingly.
Another example could be a system configuration model defined in XML. As with the security model, system configuration can be used either directly as XML, or to generate a SQL script to be loaded into the database. Also, generation of the code to access system configuration has the same benefits as the ones described for the security model above.
XML based modeling described herein has been successfully applied to several large-scale Transportation Management Systems (TMS) which consisted of 300 to 400 business objects. The systems had three tiers with a relational SQL database, C++ business layer, and a C# rich client GUI or a web front end. Communication with the business layer was going through a proprietary protocol, but there was no framework support to ensure that the messages are always valid.
Developing an XML model of all business objects and operations they support allowed using this model in run-time to make all business layer messages conform to that interface. The model was also used in design time to generate C# data objects on the GUI side that use a flexible model-view-controller (MVC) framework, which enabled a cost-effective migration of the GUI from Visual Basic 6 to the .NET platform.
Besides the GUI objects, the model also allowed generating database tables, Stored Procedures for updating these tables and, more importantly, the base classes for business objects, which define the objects’ structure including their parent-child relationships and implement all the necessary plumbing for database create-read-update-delete (CRUD) operations.
In addition to generating all these artifacts that can be regenerated at any time after the model is updated, there have also been developed several one-time generators that create stub classes that extend the generated base classes or prototypes of the user interface forms, which can serve as a spring-board for full-scale development.
Every key element in the XML model had an associated documentation tag, which also allowed generating HTML-based documentation for all business objects that is easy to browse and helps better understand the business model. On top of that, these description tags are also used in run-time to provide context-sensitive help on various fields to the users.
As a result, the developers were focusing more on the business model and the business logic of the system rather than on low-level plumbing, which resulted in significant reduction in development and maintenance time as well as in overall improvement of the product quality.
Model-driven engineering coupled with code generation can provide enormous benefits in terms of developers’ productivity, reduced development and maintenance costs, shorter time-to-market, and improved product quality.
Using XML technologies for modeling, validations, transformations, and code generation proves to be a pretty low-cost and yet extremely powerful approach to model driven development.
- 25th September, 2008: First version of this article.