next up previous
Next: 1.4.2 The Composite Pattern Up: 1.4 The Union and Previous: 1.4 The Union and

1.4.1 Member Hoisting

The preceding Java program can be improved by eliminating duplicated code in the subclasses extending CityEntry. The concrete classes forming a union are called variants. Note that the fields name, address, and phone appear in all three variants of the abstract class CityEntry. So do the definitions of the corresponding accessors getName, getAddress, and getPhone. These repeated member definitions can be hoisted into the abstract class CityEntry yielding the following Java code:

abstract class CityEntry {
  String name, address, phone;

  String getName()    { return this.name; }	
  String getAddress() { return this.address; }
  String getPhone()   { return this.phone; }
}

class BusinessEntry extends CityEntry {
  String city, state;

  BusinessEntry(String n, String a, String p, String c, String s) {
    this.name    = n;
    this.address = a;
    this.phone   = p;
    this.city    = c;
    this.state   = s;
  }

  String getCity()  { return this.city; }
  String getState() { return this.state; }	
}

class GovernmentEntry extends CityEntry {
  String city, state, government;

  GovernmentEntry(String n, String a, String p, String c, String s, String g) {
    this.name       = n;
    this.address    = a;
    this.phone      = p;
    this.city       = c;
    this.state      = s;
    this.government = g;
  }

  String getCity()       { return this.city; }
  String getState()      { return this.state; }	
  String getGovernment() { return this.government; }	
}

class ResidentialEntry extends CityEntry {

  ResidentialEntry(String n, String a, String p) {
    this.name    = n;	
    this.address = a;
    this.phone   = p;
  }
}


Finger Exercise In the preceding code, the abstract class CityEntry has three concrete subclasses: ResidentialEntry, BusinessEntry, and GovernmentEntry. By applying some very simple program transformations, you can eliminate more duplicate code in the CityEntry class and subclasses by inserting a new abstract class NonResidentialEntry between CityEntry and the concrete classes BusinessEntry and GovernmentEntry hoisting the common members of these concrete classes. After this addition, the class CityEntry still has only three concrete subclasses but only one of them is an immediate subclass. The other immediate subclass is NonResidentialEntry. Test your code using DrJava.


Finger Exercise Note that the constructor for each concrete subclass of CityEntry replicates the code for initializing the fields address and phone defined in the abstract class CityEntry. Similarly, the constructor for each concrete subclass of NonResidentialEntry replicates code for initializing the fields city and state. This code replication can be eliminated by defining constructors for the abstract classes CityEntry and NonResidentialEntry and inserting a call on the special method name super at the beginning of each concrete class constructor.

In the body of a constructor for a class C, the reserved word super can be used as a method name to to invoke a constructor in the superclass of C. In such an invocation, the method name super must be followed by an appropriate argument list enclosed in parentheses just like any other method call. (For more information on super calls, consult a Java reference book such as Thinking in Java by Eckel, The Java Programming Language by Arnold and Gosling, or Java in a Nutshell by Flanagan.)

Eliminate constructor code replication in the CityEntry class hierarchy. Test your code using DrJava.


Member hoisting is a special form of the general concept of code factoring. Code factoring is any transformation that eliminates repeated code. In functional languages like Scheme, code factoring is typically accomplished by introducing a new function with a repeated code pattern as its body. Each instance of the repeated pattern is replaced by an appropriate call on the new function. In some cases, the arguments to the pattern are procedures. This form of code factoring can be implemented in several different ways in Java. If all of the code repetitions appear within a class hierarchy for which the programmer has control of the source, then a method can be introduced in the most restrictive subclass that includes all of the occurrences of the repeated pattern. Each occurrence can be replaced by an invocation of the introduced method. In some cases, the arguments to the method are command objects (discussed in Section 1.8) representing procedures.

Java Design Rule: never repeat code in the variant classes in a union type. Hoist any repeated code into methods defined in an abstract superclass.1.2 while variants B and C share code for method n. In this case, either the code for method m or the code for method n can be hoisted but not both. More complex factoring methods are possible (using, for example, the command pattern discussed in Section 1.8), but they are typically not worth the complication.


next up previous
Next: 1.4.2 The Composite Pattern Up: 1.4 The Union and Previous: 1.4 The Union and
Corky Cartwright 2003-07-07