프로젝트를 진행하면서 Builder 패턴의 유용함을 더욱 체감 중이다.
예를 들어 다음과 같은 클래스 Person이 있다고 하자.
public class Person {
private String name;
private int age;
private String address;
private String phoneNumber;
private String email;
private String job;
}
Builder 패턴을 사용하지 않았을 경우 필요에 따라 다음과 같이 수많은 생성자들이 있어야 한다.
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public Person(String name, int age, String address, String phoneNumber) {
this.name = name;
this.age = age;
this.address = address;
this.phoneNumber = phoneNumber;
}
public Person(String name, int age, String address, String phoneNumber, String email) {
this.name = name;
this.age = age;
this.address = address;
this.phoneNumber = phoneNumber;
this.email = email;
}
public Person(String name, int age, String address, String phoneNumber, String email, String job) {
this.name = name;
this.age = age;
this.address = address;
this.phoneNumber = phoneNumber;
this.email = email;
this.job = job;
}
// .......으아악
그 외에도 다음과 같은 불편함 점들이 있다.
- 생성자 호출 시 인자의 순서를 고려해야 한다는 점도 불편한 점들 중 하나이다.
- Person 클래스에 새로운 필드를 추가하고 싶을 때 그에 해당하는 생성자의 인자도 추가되어야 한다. 그렇게 되면 위의 예시처럼 생성자가 많아지게 됨은 물론 유지보수 측면에서 불편한 점이 너무 많다.
- 또한, 생성자에 너무 많은 인자가 있는 경우 인자가 어떤 의미를 갖는지 파악하기 힘들다는 단점이 있다.
Builder 클래스
이럴 때 Builder 패턴을 사용하면 객체 생성 과정을 단순화 할 수 있다.
다음은 User 클래스를 위한 Builder 클래스의 예시이다.
public class User {
private final String name;
private final int age;
//.......생략
private User(Builder builder) {
this.name = builder.name;
this.age = builder.age;
}
// ----- Builder 클래스 -----
public static class Builder {
private String name;
private int age;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
//.......생략
public User build() {
return new User(this);
}
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
Builder 클래스는 User 클래스를 생성하는데 필요한 각각의 필드를 지정할 수 있도록 메서드를 제공해주는 클래스이다.
private User(Builder builder){
//.......
}
User 클래스의 생성자는 private 으로 선언되어 있으므로 User.Builder 클래스에서만 User 객체를 생성할 수 있다.
즉, build() 메서드를 사용하면 User 객체를 생성하고 반환할 수 있다.
@Builder 어노테이션
특히 Spring 프로젝트를 진행하면서 Lombok 라이브러리에서 제공하는 @Builder 어노테이션을 사용하면 다음과 같이 Builder 패턴을 더욱 쉽게 구현할 수 있다.
@Builder
public class User {
//.......
}
User user = User.builder()
.name("John Doe")
.age(30)
//.....
.build();
@Builder 어노테이션을 사용하면 Builder 클래스를 직접 작성하지 않아도 되어서 코드를 간결하게 작성할 수 있다.
만약 필드에 변경이 생겨나도 Builder 클래스를 수정하지 않아도 되므로 유지보수성이 높아진다는 장점이 있다.
'[Spring] > Spring 정리' 카테고리의 다른 글
트랜잭션과 @Transactional (2) | 2023.03.15 |
---|---|
Spring 과 Spring Boot 의 차이 (0) | 2022.10.09 |
API - 3 (PUT, DELETE) (0) | 2022.09.21 |
REST / REST API / RESTful 간단히 정리 (0) | 2022.09.21 |
API - 2 (GET, POST) (0) | 2022.09.21 |