
We have a complex process to construct an object involving multiple steps, then builder design pattern can help us.
In Builder we remove the logic related to object contruction from code & abstract it in separate classes.
Builder
Prototype
clone method, and needs to modify existing code so may not work with legacy code.withXXX methods and call build(). If required properties are missing, build method should provide suitable defaults or throw an exception.public class UserDto {
private String name;
private String address;
private String age;
public String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
private void setAddress(String address) {
this.address = address;
}
public String getAge() {
return age;
}
private void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return String.format("Name: %s\nAge: %s\nAddress: %s", name, age, address);
}
public static UserDtoBuilder getBuilder() {
return new UserDtoBuilder();
}
public static class UserDtoBuilder {
private String firstName;
private String lastName;
private String age;
private String address;
private UserDto userDto;
public UserDtoBuilder withFirstName(String fname) {
firstName = fname;
return this;
}
public UserDtoBuilder withLastName(String lname) {
lastName = lname;
return this;
}
public UserDtoBuilder withBirth(LocalDate birth) {
Period ageInYears = Period.between(birth, LocalDate.now());
age = Integer.toString(ageInYears.getYears());
return this;
}
public UserDtoBuilder withAddress(Address address) {
this.address = address.getHouseNumber() + ", " + address.getStreet() + ", " + address.getCity() + ", " + address.getState() + ", " + address.getZipCode();
return this;
}
public UserDto build() {
this.userDto = new UserDto();
userDto.setName(firstName + " " + lastName);
userDto.setAddress(address);
userDto.setAge(age);
return this.userDto;
}
public UserDto getUserDto() {
return this.userDto;
}
}
}