JeeWiz Home  
The Model-Driven System Builder

JeeWiz Architect's Guide
 
Contents  >   9.  Patterns
 


9.1 Motivation

To understand why patterns are useful, consider a 'singleton' pattern.

To be a singleton, the class will have a 'getInstance()' method that gets the singleton instance of the class, and a static instance variable holding the single instance once allocated. Crucially, it will also have other business methods or (non-business) methods.

In other words, a singleton is basically a class, but with some added bits. Without using patterns, you can add these on using a special-purpose template at the rendering stage:

   class $name
   {
     static    
       private $name instance = new $name();
     protected $name() {}   // prevent others using 
     public    $name getInstance()
     {
       return instance;
     }
     // render other methods.
   }
This is a template-based implementation of the singleton pattern. However, the problem is that we now need to render all the other members in the same pattern. This would require duplicating all the existing code in the rendering of 'jwclass'. Furthermore, we have a restricted implementation of the 'getThe...()' method: what if we wanted to log or trace this method, in line with prevailing standards?

A better approach is to add the extra bits into ('embellish') the specification. To implement a singleton, we need to embellish the current class with the 'instance' field, the protected constructor and the 'getInstance' method. In other words, the additions - if we could render them as a template - would look like this:

   <field        name="instance" 
                 type="$name"
                 default="new $name()"
                 static="true"
                 access="private"
                 writeable="false"
                 />
   <constructor  access="protected"
                 implement-in-base="true"
                 />
   <method       name="getThe${nameCapitalised}"
                 return-type="$_rc"
                 access="public"
                 implement-in-base="true"
                 >
This is how the pattern mechanism in JeeWiz operates. It renders a script like the text above, resolving name references etc., such as $name. The output of this rendering, with final names substituted, is then used as further input.

Why is this better - better enough so that the extra bulk required to write XML is worthwhile?
  1. This matches how patterns and components are discussed and described. The issue is what are the derivative objects, fields and methods and their characteristics. There is normally no concern for the details of implementation in a particular environment. JeeWiz supports this approach directly: the pattern operates by enhancing the model; the rendering into the environment is then added on.
  2. By enhancing the model, we can use all the facilities of the standard rendering. Creating a pattern becomes a fairly simple process of creating some extra XML to describe the additional specification. It is separate from the templates that will create the eventual build products (e.g. Java class). This means that when the newly created class (because this is typically what it is) is rendered to the final textual products, it will automatically pick up settings for
    • logging and tracing - any newly created classes or methods will be fully traced, use log4J/console traced, depending on the configuration, not on the pattern
    • the language to output - patterns create specifications classes. Whether they are Java (or C#, C++ etc.) is determined by other aspects of the build
    • at a higher level, where patterns create 'pages', these can be rendered using the currently-configured UI mechanism. The pattern does not need to know if the page will be implemented by Struts, Swing, JSP or the latest best thing.
  3. It is possible to create hierarchies of patterns (which is not possible with templates because they are always the last step in the process). For example:
    • Simple classes are represented as model objects and are typically rendered with a template (they are 'level 0' say - they do not create further specification objects).
    • Pattern components create one object based on another, or add in attributes to the current object. For example, creating a single proxy class from a business object would be a pattern component. These can be thought of as 'level 1' - the most basic part of patterns.
    • Patterns to do something useful typically involve creation of multiple components. For example, the business object's pattern may involve creating factories and interfaces as well as a proxy class. So these are 'level 2' - we are aggregating the level 1 pattern components.
    • Because patterns typically create other specification objects, there will normally be a cascade of patterns firing as a result of one pattern. While these will often result in 'smaller' objects (e.g. entities create interfaces), it is also possible for patterns to create 'big' objects in adjacent tiers - for example, an entity can create its corresponding data-view automatically. This sort of 'level 3' pattern is called a 'mega-pattern': it can effectively create whole tiers from adjacent tiers.

      It turns out that mega-patterns would be impractical to write as templates, but are remarkably straightforward as patterns.


9.1.1  Simple XML
In an earlier section, we discussed why JeeWiz uses a simple XML form for its models.

Hopefully, the simplicity of the above example demonstrates how valuable a simple XML form for the model is. In contrast, a look at an XMI file as a possible alternative would be a good counter-example: as XMI is 30 to 60 times more verbose that JeeWiz XML, it would be impractical to create patterns in this way.  


Copyright (c) 2001-2008 New Technology/enterprise Ltd.