Sunday, June 12, 2011

Builder style setters or Chained invocation in Java

Setters idiom in Java is an evil and I hate it. And I don't hate it because you have to invoke setXXX methods multiple times when you have to set many fields. The most annoying thing for me is that you can only set one field in a line. This is because setter method return this stupid void. Here is the example:

public class Car {  
private int maxSpeed;
// remainder omitted

public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
// remainder omitted
}

So my code using the Car class will look like this:

Car car = new Car();  
car.setMaxSpeed(210);
car.setSpeedUnit("km/h");
car.setLength(5);
// remainder omitted


I have an idea how the life of the developers can be made easier using builder-style setters "pattern". Here is the new BETTER Car class:


public class Car {  
private int maxSpeed;
private String speedUnit;
// remainder omitted

public Car setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
return this;
}

public Car setSpeedUnit(String speedUnit) {
this.speedUnit = speedUnit;
return this;
}
// remainder omitted
}


I can now instantiate and initialize my Car object in one line (maybe wrapped but still one line of code):

Car car = new Car()  
.setMaxSpeed(210)
.setSpeedUnit("km/h")
.setLength(5)
...


What do you think? Isn't it much easier now? Of course if you extend Car class it becomes more tricky as you have to repeat all the setter methods like this:

public class Truck extends Car {  
private int capacity;
private String capacityUnit;
// remainder omitted

@Override
public Truck setMaxSpeed(int maxSpeed) {
super.setMaxSpeed(maxSpeed);
return this;
}

@Override
public Truck setSpeedUnit(String speedUnit) {
super.setSpeedUnit(speedUnit);
return this;
}
// remainder omitted
}


Looking at the better use case


The example is not very good above, so please bear with this. Actually when there is class hierarchy having full inheritance among them, example – There is a class called Person as the Base class. Now suppose GrandParent extends Person, Parent extends GrandParent, Child extends Parent. Now the common properties of these can be set by some interface say ISetter (stupid name, please ignore).


Now all the common settings can be set by implementing ISetter interface and that will be kind of one-liner, increasing the code readability.

No comments:

Post a Comment

Chitika