Saturday, 21 May 2011

The Telescoping Constructor (Anti)Pattern

The Telescoping Constructor is an example of a pattern that borders on an anti-pattern that is all too often used in projects even though there are better alternatives availble. In this pattern, your POJO has numerous constructors each taking a different number of parameters that, if the class has been written correctly, delegate to a default constructor.

public class FoodTelescopingDemo {

 
private final int id;
 
private final String name;
 
private final int calories;
 
private final int servingSize;
 
private final int fat;
 
private final String description;

 
public FoodTelescopingDemo(int id, String name) {
   
this(id, name, 0, 0, 0, "default description");
 
}

 
public FoodTelescopingDemo(int id, String name, int calories) {
   
this(id, name, calories, 0, 0, "default description");
 
}

 
public FoodTelescopingDemo(int id, String name, int calories, int servingSize) {
   
this(id, name, calories, servingSize, 0, "default description");
 
}

 
public FoodTelescopingDemo(int id, String name, int calories, int servingSize, int fat) {
   
this(id, name, calories, servingSize, fat, "default description");
 
}

 
/**
   * Main Constructor - actually builds the object
   */
 
public FoodTelescopingDemo(int id, String name, int calories, int servingSize, int fat,
      String description
) {
   
this.id = id;
   
this.name = name;
   
this.calories = calories;
   
this.servingSize = servingSize;
   
this.fat = fat;
   
this.description = description;
 
}

 
public int getId() {
   
return id;
 
}

 
public String getName() {
   
return name;
 
}

 
public int getCalories() {
   
return calories;
 
}

 
public int getServingSize() {
   
return servingSize;
 
}

 
public int getFat() {
   
return fat;
 
}

 
public String getDescription() {
   
return description;
 
}

}

There are a couple of good points about this anti-pattern: firstly it works and secondly, you can make your objects thread-safe. But, on the minus side, the multiple constructors make it difficult to use. Also, it's difficult to distinguish between parameters of the same type and it’s often the case that that there isn't a constructor that does the job you want so you end up either adding a new constructor or using a null parameter. The code below demonstrates how a Telescoping Constructor is used...

    // Use of the Telescoping Constructor
   
FoodTelescopingDemo telescopingConstructor1 = new FoodTelescopingDemo(1,
       
"My Name");
   
// Use the new object
   
telescopingConstructor1.toString();
   
    FoodTelescopingDemo telescopingConstructor2 =
new FoodTelescopingDemo(1,
       
"My Name", 4, 3);
   
// Use the new object
   
telescopingConstructor2.toString();
   
    FoodTelescopingDemo telescopingConstructor3 =
new FoodTelescopingDemo(1,
       
"My Name", 4, 3, 34);
   
// Use the new object
   
telescopingConstructor3.toString();

There are tidier, better, safer options that using this pattern: more on that later....

1 comment:

Henno Vermeulen said...

I agree with you that telescoping constructors are not ideal. I do think for a small number of parameter it may be the simplest choice though. (If only Java had default arguments).

However I think your example could be cleaner and it is not really an example of a telescoping constructor. You duplicate the default values by letting each constructor i call constructor n directly. You would get a "telescope" without duplicated default values when you let constructor i call constructor i+1 .