Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactor to use Builder pattern or Telescoping constructor pattern

According to Effective Java 2ed Item 2

telescoping constructor pattern, in which you provide a constructor with only the required parameters, another with a single optional parameter, a third with two optional parameters, and so on, culminating in a constructor with all the optional parameters.

An example of constructors of the class applying this pattern is borrowed from When would you use the Builder Pattern?

code set 1a

Pizza(int size) { ... }        
Pizza(int size, boolean cheese) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni, boolean bacon) { ... }

size is a required parameter. cheese, pepperoni, and bacon are optional parameters. Supposing that I would like to provide the constructor like below.

code set 1b

Pizza(int size) { ... }        
Pizza(int size, boolean cheese) { ... }    
Pizza(int size, boolean pepperoni) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni, boolean bacon, int price, int) { ... }

Another example is that

code set 2

public AttributeKey(String key, Class<T> clazz)
public AttributeKey(String key, Class<T> clazz) 
public AttributeKey(String key, Class<T> clazz, @Nullable T defaultValue, boolean isNullValueAllowed)
public AttributeKey(String key, Class<T> clazz, @Nullable T defaultValue, boolean isNullValueAllowed, @Nullable ResourceBundleUtil labels)

The two latest example I gave didn't follow the characteristic of telescoping constructor as code set 1a did

  1. Are code set 1b and 2 included in telescoping constructor? if not, what is it called?
  2. Comparing to using Builder Pattern, which one (between Builder and pattern of code set 1a,2) provides more benefits
like image 487
BB. Avatar asked Apr 09 '11 05:04

BB.


2 Answers

What is this pattern of constructors'parameters called?

This is not a design pattern per se, but it is a programming technique called constructor chaining.

Comparing to using Builder Pattern, which one provides more benefits

The same SO question: When would you use the Builder Pattern? that you have borrowed also explains the difference nicely. In short, builder is preferred over constructor chaining as it can result in proliferation of constructors which can become hard to maintain.

Hope that helps.

like image 97
Nilesh Avatar answered Oct 18 '22 02:10

Nilesh


In this case, I would go for either the builder or a different mechanism where the caller can pass a collection of toppings. If you need to validate what toppings are allowed, you can do that in the constructor or the Toppings setter. The telescoping/chaining constructor approach may require you to add additional constructors in the future to handle additional combinations of toppings, whereas a collection approach will handle any scenario automatically. I would also avoid having specific properties in the pizza class for different types of toppings. What if you need to handle extra cheese? A single cheese boolean will not handle that. The Topping class can be a full-fledged object with subclasses, or you could replace it with just a string.

public class Pizza
{
    // setters don't have to be private...
    public int Size {get; private set;}
    private List<Topping> toppings {get; private set;}

    public Pizza(int size) : this(size, new List<Topping>()) // call the other ctor with an empty list of toppings
    {
    }

    public Pizza(int size, List<Topping> toppings)
    {
        Size = size;
        Toppings = toppings;
    }
}
like image 2
Andy White Avatar answered Oct 18 '22 02:10

Andy White