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
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.
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With