next up previous
Next: 1.5.2 The Composite Pattern Up: 1.5 The Union and Previous: 1.5 The Union and

1.5.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 concrete variants or simply 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:

/**  CityEntry := 
       BusinessEntry(String, String, String, String, String) 
     + GovernmentEntry(String, String, String, String, String, String)
     + ResidentialEntry(String, String, String)
 */
abstract class CityEntry {

  String name;	
  String address;
  String phone;

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

class BusinessEntry extends CityEntry {

  String city;
  String 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;
  String state;
  String 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.


Optional 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 using the special method name super to invoke these constructors 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 Bruce Eckel, The Java Programming Language by Ken Arnold and James Gosling, or Java in a Nutshell by David 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, the standard code factoring is typically accomplished by introducing a new $\lambda$-abstraction (nested procedure) with a repeated code pattern as its body. Each instance of the repeated pattern is replaced by an appropriate call on the new abstraction. In some cases, the arguments to the pattern are procedures.

This form of code factoring can be implemented in several different ways in Java. The simplest and most common factoring technique is to use inheritance. 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.5


next up previous
Next: 1.5.2 The Composite Pattern Up: 1.5 The Union and Previous: 1.5 The Union and
Corky Cartwright
2001-08-02