Transforming Models

Posted by on in Blogs
In my last post, "'Model' Is an Overloaded Word," I discussed several types of models which might be present in an MVC application. But I limited the discussion to models which are actually in the executable.  There may of course be additional models, such as ERDs, UML models, etc., which exist in the development environment, but are not actually part of the executable.

It is often the case that we use software tools to transform these conceptual models into executable code of one form or another.  For example, a database management tool may know how to transform an ERD into physical database metadata.  A UML design surface might know how to transform a UML model into compilable code.  Most object-relational mappers designed for non-dynamic languages such as C# and Java seem to work by transforming some kind of schema file, usually XML, into compilable code.  And so on...

Inside the application, at runtime, a similar transformation of models occurs.  Let's examine the pipeline which results in transforming data in a database into HTML which a user can view:

  1. The user invokes an action.  This starts a chain of events ultimately resulting in a call to the database server in the form of an SQL statement.  The database server transforms its will on-disk representation of the data into a result set understandable by the data access components.

  2. The object-relational mapping transforms the result set into entity instances — instances of classes in a form useful to implementers of business logic.

  3. If the application is using the Repository pattern, these entity instances may be passed directly to the controller.  Or they may be transformed into lightweight data access objects.

  4. Whatever their form, the entity instances will be wrapped up into a model containing all of the information required to render a view.

  5. The view will transform the entities into a different kind of model: HTML.

  6. The browser will transform the HTML into a DOM which can be further manipulated via JavaScript.

A similar series of transformations between model types occurs when we accept user input and store it back in the database.

These series of transformations are not so different from the transformations I mentioned above, like transforming a UML model into executable code.  Indeed, compilation itself is just another kind of model transformation, changing a representation which is (hopefully!) readable by a developer into a representation readable by a machine.  If the transformation is lossless, then it can probably be done in both directions.

So one way to look at an application is as a series of transformations from one model type to another, not only in execution, but also in the manner in which the application itself is built. However, the transformations are performed with wildly different implementations:

  • A special-purpose executable (e.g., a compiler) can be used to transform the models. Such executables are typically fairly limited; most compilers support only one language, and do not, for example, transform UML models into code.

  • We can write code in a high-level language to transform the models, often in a way which is dependent on the specific types or properties involved (e.g, A.Foo = b.Foo), or possibly at a more generic level, such as with a common interface.

  • We can create informally-specified principles for model transformation, such as "convention over configuration," which are often sufficient to completely specify the transformation without requiring code.

  • We can create systems of rules for model transformation. The formal name for such a system of rules is an algebra, not to be confused with the elementary algebra you learned in high school. This is a set of simple rules designed to be composed into more advanced transformations. One such system is relational algebra, which surfaces (in a heavily mutilated form) in SQL databases.

Now, my purpose in this post is not to claim that one of these methods is superior to the others.  "The best tool for the job" still applies.  The idea of model transformation, however, encompasses more parts of a software system than many programmers commonly suppose.  The notion of treating your source code as a model which can be transformed via an algebra into an equivalent, but faster and provably correct, application is not new, but is perhaps surprising to programmers who have not studied functional programming. So the question is not "How do I create an instance of Bar from an instance of Foo?," but "What kind of transformation is this, and how does it fit into the context of the other transformations I'm performing in this application?"

Such a worldview makes technologies like Haskell's monads and LINQ, designed as generic solutions for the problem of transforming one type of set into another, even more interesting than they already are.


Check out more tips and tricks in this development video: