The builder pattern is used in software development to construct complex objects in a step-by-step manner, without having to specify the complex details of object creation in the main code.
⇒ 복잡한 객체들을 단계별로 생성할 수 있도록 하는 생성 디자인 패턴
// 다양한 생성자를 통한 객체 생성
public class User {
private final String firstName; // 필수값
private final String lastName; // 필수값
private int age; // 선택값
private String phone; // 선택값
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public User(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public User(String firstName, String lastName, String phone) {
this.firstName = firstName;
this.lastName = lastName;
this.phone = phone;
}
User user1 = new User("John", "Doe");
User user2 = new User("John", "Doe", 30);
User user3 = new User("John", "Doe", "123456789");
public class User {
private final String firstName;
private final String lastName;
private final int age;
private final String phone;
private User(UserBuilder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.phone = builder.phone;
}
public static class UserBuilder {
private final String firstName; // 필수값
private final String lastName; // 필수값
private int age; // 선택값
private String phone; // 선택값
public UserBuilder(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public User build() {
return User(this.firstName, this.lastName, this.age, this.phone);
}
}
}
User user = new User.UserBuilder("John", "Doe")
.age(30)
.phone("123445678")
.build();
@Builder
어노테이션 사용⇒ @Builder
어노테이션은 Builder Pattern을 사용하여 객체를 생성하도록 도와준다.
클래스 레벨과 생성자 레벨에 선언하여 사용할 수 있다.
⇒ 클래스 레벨에 @Builder
어노테이션을 선언하면, @AllArgsConstructor(access=AccessLevel.PACKAGE)
와 동일하게 생성자를 생성한다.
⇒ 주의: 다른 생성자가 이미 있을 경우 제대로 동작하지 않을 수 있다.
@Builder
public class User {
private String firstName;
private String lastname;
private int age;
private String phone;
}
// 컴파일 후
public class User {
private String firstName;
private String lastName;
private int age;
private String phone;
User(final String firstName, final String lastName, final int age, final String phone) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.phone = phone;
}
public static UserBuilder builder() {
return new UserBuilder();
}
public static class UserBuilder {
private String firstName;
private String lastName;
private int age;
private String phone;
public UserBuilder() {}
public UserBuilder firstName(final String firstName) {
this.firstName = firstName;
return this;
}
public UserBuilder lastName(final String lastName) {
this.lastName = lastName;
return this;
}
public UserBuilder age(final int age) {
this.age = age;
return this;
}
public UserBuilder phone(final String phone) {
this.phone = phone;
return this;
}
public User build() {
return User(this.firstName, this.lastName, this.age, this.phone);
}
public String toString() {
return "User.UserBuilder(firstName=" + this.firstName + ", lastName=" + this.lastName + ", age=" + this.age + ", phone=" + this.phone + ")";
}
}
}
User user = new User.builder()
.firstName("John")
.lastName("Doe")
.age(30)
.phone("123456789")
.build();
⇒ 클래스 레벨과 다른점은 생성자에 선언한 파라미터 필드에 한해서반 빌드 패턴이 적용된다는 것이다.
public class User {
private String firstName;
private String lastName;
private int age;
private String phone;
@Builder
User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
// 컴파일 후
public class User {
private String firstName;
private String lastName;
private int age;
private String phone;
User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public static UserBuilder builder() {
return new UserBuilder();
}
public static class UserBuilder {
private String firstName;
private String lastName;
public UserBuilder() {}
public UserBuilder firstName(final String firstName) {
this.firstName = firstName;
return this;
}
public UserBuilder lastName(final String lastName) {
this.lastName = lastName;
return this;
}
public User build() {
return new User(this.firstName, this.lastName);
}
public String toString() {
return "User.UserBuilder(firstName=" + this.firstName + ", lastName=" + this.lastName + ")";
}
}
}
User user = new User.builder()
.firstName("John")
.lastName("Doe")
.build();