public class Period {
private final DateTime start;
private final DateTime end;
...
}
How can we create instance of Period ?
1. No-arg constructor + setters
This is probably the worst way. It would look like that:final Period period = new Period(); period.setStart(startDate); period.setEnd(endDate);Advantages:
- None
- you create empty object
- it takes three lines of code
- it's muttable so you never know if the object is consistent
- you can make stupid mistakes like invoke same setter twice with different parameters and so on
public static class Address {
private final String street;
private final String houseNumber;
private final String postalCode;
}
Some user (let's say Ben) registers in your system with the following address:
new Address("Long street", "16a", "50-500");
After few days Ben finds better flat on the same street say:
Long Steet, 46d, 50-500
What now ? Should we update existing address or create new one ?
Some people would say update but what if this house belongs to other post therefore should have other postal code ?
I think that we should in such case always create new object. I have a validator which checks Address instance so I am sure that the address is correct. When I create and validate object I get consistent and correct object so immutable objects should be created whenever it's possible.
2. All-args constructor + getters
Advantages:- object is immutable
- it takes one line to create instance
- it's not very readable (espiecially for people who aren't developers)
- when constructor's parameters are of the same type it's easy to swap them by mistake
3. Builder
I think it's best solution in this case. Most people use builder pattern for classes which have a lot of fields. In my opinion builder is a perfect pattern to create instance of class which has only two fields. Let's get back to Period class: @Getter
public static class Period {
private final DateTime startDate;
private final DateTime endDate;
public static Builder newPeriodThatStarts(final DateTime startDate) {
return new Builder(startDate);
}
private Period(final DateTime startDate, final DateTime endDate) {
this.startDate = startDate;
this.endDate = endDate;
}
public static class Builder {
private final DateTime startDate;
private Builder(final DateTime startDate) {
this.startDate = startDate;
}
public Period andEnds(final DateTime endDate) {
return new Period(startDate, endDate);
}
}
}
And this is how you instantiate Period instance:
public static void main(String [] args) {
Period period = newPeriodThatStarts(now()).andEnds(now().plusDays(1));
Period anotherPeriod = newPeriodThatStarts(new DateTime(2016, 2, 15, 10, 0, 0)).andEnds(now());
}
Advantages:- object is immutable
- it takes one line to create instance
- it's very readable even for someone who isn't software developer
- you have to create a builder (or use lombok)