How do you build a Bean pattern?

The Java bean pattern is fairly straightforward. A bean has a number of properties, each of which has a type. While the properties and types will change from bean to bean, there is a pattern to the way the names and types of the properties are written into the code and surrounded by boilerplate. If you've written a bean by hand, you've probably noticed a number of nested patterns in the bean's implementation.

The high-level pattern

The bean class can always be written as the following syntactic sequence:

  1. The package statement
  2. The class definition statement
  3. A block of declarations, one for each property
  4. A set of "getters and setters", one for each property
  5. The closing curly bracket

Within the block of declarations is a single line:

private <property-type> <property-name>;

The code for each property's getter and setter is a bit more complex, but only in that it has more boiler plate and the name and type are used in several places each. Ignore the uppercasing of the name in places for now:

  /** 
   * Gets the <property-name> 
   * @return Returns a <property-type> 
   */ 
  public <property-type> get<property-name>() { 
      return <property-name>; 
  } 
  
  /** 
   * Sets the <property-name> 
   * @param <property-name> The <property-name> to set 
   */ 
  public void set<property-name>(<property-type> <property-name>) { 
     this.<property-name> = <property-name>; 
  }

After an exhaustive (yet short) analysis of the boilerplate (called the pattern template from here on), we see that there are just a few pieces of information required to "fill in" the template. Some of this information repeats for every property, some information applies to the entire class. We can model and capture that information in XML, of which the following is just an example.

<bean class="Teacher">
   <package>com/ibm/education</package>
   <property name="first" type="String"/>
   <property name="last" type="String"/>
   <property name="grade" type="int" />
   <property name="room" type="String" />
</bean>

We refer to this XML as the application definition, since it represents what is different about this particular application. Another bean (another application) would have different XML, but every application definition for this pattern would have the same structure (schema) in terms of element and attribute names.

Once the application definition has been defined, we can go back to the pattern template and describe how to merge the application definition with the template text. We define this merging using tags that act upon individual elements and sets of elements from the XML. The resulting pattern template is shown below.

package <content node="/bean/package" format="DP"/>;

public class <attr node="/bean" name="class"/> {

<iterate nodes="/bean/property" name="curProp" >
   <attr node="curProp" name="type"/> <attr node="curProp" name="name"/>;
</iterate>
	
    /* Constructor for <attr node="/bean" name="class"/> */

	public<attr node="/bean" name="class"/>() {
   		super();
	}

<iterate nodes="/bean/property" name="curProp" >
	/**
	 * Gets the <attr node="curProp" name="name"/>
	 * @return Returns a<attr node="curProp" name="type"/>
	 */
	public<attr node="curProp" name="type"/> getGrade() {
    		return grade;
	}
	/**
	 * Sets the <attr node="curProp" name="name"/>
	 * @param <attr node="curProp" name="name"/> The <attr node="curProp" name="name"/> to set
	 */
public void set<attr node="curProp" name="name" format="U1"/&gt(<attr node="curProp" name="type"/> <attr node="curProp" name="name"/>) {
    		this.<attr node="curProp" name="name"/> = <attr node="curProp" name="name"/>
	}
</iterate>

}

Just a few comments on the above tags and template:

  1. The content tag is used to insert into the template the content of a tag from the application definition. The package tag, for example, contains the directory name in the source tree for the source file and we insert that into the package statement. Since the levels of the package are seperated by perioids and not slashes, we use the format attribute to convert the string from directory format to package format.
  2. The attr tag is used to insert the value of an attribute of an appdef tag into the template. In one case above, we need to uppercase the first letter of the value to create the getter and setter names, so we use format="U1".
  3. The iterate tag builds a collection of elements from the applicaiton definition that meet a set of criteria and then iterates over that set. For each iteration, the current element is assigned a name (in both the above cases we use "curProp") with which that element can be referenced by nested tags (like attr and content). For each iteration, the iterate tag will process its content and any tags nested.
  4. There is no restriction to the ways and depth you may nest these template tags.


© Copyright IBM Corporation 2000, 2005. All Rights Reserved.