Overview
What is the telescoping constructor problem? This is a problem when overloaded methods that contains additional parameters exist in a class. An example would be:
public void AddFruit(string type) { }
public void AddFruit(string type, string color) { }
public void AddFruit(string type, string color, string taste) { }
A telescoping constructor problem can lead to messy code that becomes not only complicated to read, but we can use a better pattern to provide arguments to the method.
Creating a new object in lieu of the parameters
One way to avoid the telescoping contructor problem is to instead create a new object in place of the parameters
var fruitDetails = new FruitDetails() {
Type = "Apples",
Color = "Green",
Taste = "Sour"
}
// The method can then accept a FruitDetails object instead of multiple parameters
public void AddFruit(FruitDetails details) { }
What about a builder pattern?
Using a new object is pretty good but there are times when you have too many attributes on the object and perhaps as the API designer, you want to impose rules on which attributes can be used.
For example, if with FruitDetails
you want to make sure that Apples
can only be Red
or Green
a builder pattern can be used.
var fruitDetails = new FruitDetails()
.WithType("Apple")
.WithColour("Green")
.Build();
// This can then fail during execution with an error message
public class FruitDetails() {
public string Type {get; set;}
public string Colour {get; set;}
public FruitDetails() {
}
public FruitDetails WithType(string type) {
// Set type
}
public FruitDetails WithColour(string colour) {
// Set colour
}
public FruitDetails Build() {
// Validate that the colour and type are correct
// if not throw an exception
}
}
The really nice thing about using a builder pattern is that it is easy to read since we’re using method chaining and fluent syntax.
Method chaining
Whilst reading up on fluent syntax, I came to realize that method chaining is not the same thing as fluent syntax. Method chaining refers to a technique where one method call is used as the argument for another method call.
var apples = new Fruit().WithColour("red").WithShape("round");
The above is considered method chaining.
Fluent syntax
Fluent syntax is a programming style that uses mostly method chaining with the intention of making code readable. The difference between this and method chaining is that method is a way of producing code that follows fluent syntax.