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)
No comments:
Post a Comment