빌더 패턴(Builder Pattern)이란?
: GoF(Gang of Four) 디자인 패턴 중 생성패턴(Creational)에 해당하며, 빌더패턴은 복잡한 객체를 생성하는 클래스와 표현하는 클래스를 분리하여 동일한 절차에서도 서로 다른 표현을 생성하는 방법을 제공한다. 자바에서는 생성자에 값을 담아 보낼때, 어떤 값을 전달하는지 알기가 힘들며, 또 인자가 많아지면 더더욱 확인이 어려워진다.
- GoF 디자인패턴 더 알아보기: https://velog.io/@namezin/GoF-design-pattern
점증적 생성자 패턴(telescoping construtor patter)
: 클래스 내에 오버로딩을 통해 생성자를 여러개 작성하는 것
= 장점
- 선택적으로 인자를 받을 수 있다.
= 단점
- 인자가 추가되는 상황이 발생한다면, 유지보수가 어렵다.
- 코드 가독성이 떨어진다. 생성자에 들어가는 데이터가 무슨 데이터인지 확인이 어려움 (IDE에서 param명이 무엇인지 보여주는 기능으로 어느정도 극복은 가능하지만..)
class Car {
private String carNo;
private String carName;
private String companyName;
private int displacementVolume;
private String issueDate;
// ....
// ....
// ....
public Car(String carNo, String carName, String companyName, int displacementVolume) {
this.carNo = carNo;
this.carName = carName;
this.companyName = companyName;
this.displacementVolume = displacementVolume;
}
public Car(String carNo, String carName, String companyName, int displacementVolume, String issueDate) {
this.carNo = carNo;
this.carName = carName;
this.companyName = companyName;
this.displacementVolume = displacementVolume;
this.issueDate = issueDate;
}
}
자바 빈 패턴(Java Bean Pattern)
: 자바 빈객체를 만들때 기본적으로 사용하는 패턴이다.
= 장점
- 인자의 의미를 파악하기가 쉽다. (물론 필드명을 잘 지어야하겠죠..?)
- 복잡하게 여러 개의 생성자를 만들 필요가 없다.
= 단점
- 객체의 일관성이 깨짐
- setter 메소드의 존재로, 불변성의 확보가 어렵다.
public static void main(String[] args) {
Car car = new Car();
car.setCarNo("12차3456");
car.setCarName("코나2020");
car.setCompanyName("현대");
car.setDisplacementVolume("1591");
car.setIssueDate("2020-04-09");
}
class Car {
private String carNo;
private String carName;
private String companyName;
private int displacementVolume;
private String issueDate;
public String getCarNo() {
return carNo;
}
public void setCarNo(String carNo) {
this.carNo = carNo;
}
public String getCarName() {
return carName;
}
public void setCarName(String carName) {
this.carName = carName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public int getDisplacementVolume() {
return displacementVolume;
}
public void setDisplacementVolume(int displacementVolume) {
this.displacementVolume = displacementVolume;
}
public String getIssueDate() {
return issueDate;
}
public void setIssueDate(LocalDate issueDate) {
this.issueDate = issueDate;
}
}
점증적 생성자 패턴과 자바 빈 패턴의 장점을 결합한 것이 빌더 패턴이다.
클라이언트 코드에서 필요한 객체를 직접 생성하는 대신, 그 전에 필수 인자들을 전달하여 빌더 객체를 만든 뒤, 빌더 객체에 정의된 설정 메서드들을 호출하여 인스턴스를 생성한다.
빌더 패턴 사용 예제
public static void main(String[] args) {
// 빌더패턴 사용
Car car = new Car.Builder("12차3456")
.carName("코나")
.companyName("현대")
.displacementVolume("1591")
.build();
}
public class Car {
private String carNo;
private String carName;
private String companyName;
private int displacementVolume;
private String issueDate;
// 외부에서는 접근할 수 없고, Builder 클래스로 사용가능하도록함
private Car(Builder builder) {
this.carNo = builder.carNo;
this.carName = builder.carName;
this.companyName = builder.companyName;
this.displacementVolume = builder.displacementVolume;
this.issueDate = builder.issueDate;
}
public static class Builder { // 외부에서 Car.Builder() 형태로 접근 가능하게 static 사용
String carNo;
String carName;
String companyName;
int displacementVolume;
String issueDate;
public Builder(String carNo) {
this.carNo = carNo;
}
public Builder carName(String carName) {
this.carName = carName;
return this;
}
public Builder companyName(String companyName) {
this.companyName = companyName;
return this;
}
public Builder displacementVolume(int displacementVolume) {
this.displacementVolume = displacementVolume;
return this;
}
public Builder issueDate(String issueDate) {
this.issueDate = issueDate;
return this;
}
public Car build() {
return new Car(this);
}
}
}
위의 작업대신,
Lombok의 @Builder 어노테이션으로 편하게 사용할 수도 있다.
public static void main(String[] args) {
// 빌더패턴 사용
Car car = new Car.Builder("12차3456")
.carName("코나")
.companyName("현대")
.displacementVolume("1591")
.build();
}
@Builder
public class Car {
private String carNo;
private String carName;
private String companyName;
private int displacementVolume;
private String issueDate;
}
참고자료
- https://velog.io/@namezin/%EB%B9%8C%EB%8D%94Builder
- https://gonyda.tistory.com/9
'JAVA' 카테고리의 다른 글
Java - 정규표현식 정리 (0) | 2022.02.07 |
---|---|
Java - 자료구조와 컬렉션 프레임워크 (0) | 2022.01.23 |
Java - 설정 옵션 (Garbage Collector) (0) | 2021.11.01 |
Java - Garbage Collector (0) | 2021.11.01 |
Java - 데이터 타입(기본타입, 참조타입) (0) | 2021.10.20 |