빌더 패턴
2020-02-09
빌더패턴
빌더 패턴은 팩토리 패턴이나 추상 팩토리 패턴에서 객체가 많은 속성들을 갖고 있을 때 발생하는 문제를 해결하기 위해서 만들어졌습니다.
빌더패턴의 장점은 여러 개의 많은 필드 중에 값을 주고 싶은 필드만 골라서 객체를 리턴할 수 있다는 장점이 있습니다.
빌더 패턴
- 첫번 째로 내부안에 static 클래스를 만들고 외부 클래스에 있는 인자들을 전부 복사해와야 합니다. 외부 클래스 이름이 Computer라면, 빌더 클래스는 ComputerBuilder로 지어야하는 네이밍 컨벤션을 따라야 합니다.
- 자바 빌더 클래스는 모든 필요한 필드들은 public으로 된 생성자로 만들어야 합니다.
- 자바 빌더 클래스는 선택적인 필드를 만들어주는 메소드가 있어야하며 그 필드를 만들었다면 같은 Builder 오브젝트를 리턴해야 합니다.
- 마지막으로 build()를 만들어 객체를 리턴하는 메소드가 있어야합니다. 그러므로 외부 클래스의 생성자를 private로 만들어야 합니다.
빌더 패턴 예제
다음은 Computer 클래스안에 ComputerBuilder 클래스가 있는 예제 입니다.
Computer.java
public class Computer {
//required
private String HDD;
private String RAM;
//optional
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;
public String getHDD() {
return HDD;
}
public String getRAM() {
return RAM;
}
public boolean isGraphicsCardEnabled() {
return isGraphicsCardEnabled;
}
public boolean isBluetoothEnabled() {
return isBluetoothEnabled;
}
private Computer(ComputerBuilder builder) {
this.HDD=builder.HDD;
this.RAM=builder.RAM;
this.isGraphicsCardEnabled=builder.isGraphicsCardEnabled;
this.isBluetoothEnabled=builder.isBluetoothEnabled;
}
//Builder Class
public static class ComputerBuilder{
private String HDD;
private String RAM;
// optional
// 다음은 선택적 필드이므로 값을 가지는건 자유임.
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;
public ComputerBuilder(String hdd, String ram){
this.HDD=hdd;
this.RAM=ram;
}
public ComputerBuilder setGraphicsCardEnabled(boolean isGraphicsCardEnabled) {
this.isGraphicsCardEnabled = isGraphicsCardEnabled;
return this;
}
public ComputerBuilder setBluetoothEnabled(boolean isBluetoothEnabled) {
this.isBluetoothEnabled = isBluetoothEnabled;
return this;
}
public Computer build(){
return new Computer(this);
}
}
}
Computer 클래스는 오직 getter 메소드만 있고 public으로 된 생성자가 없어서 Computer 클래스 자체로는 Computer 객체를 만들지 못합니다.
빌더 패턴 테스트
다음은 빌더 패턴을 테스트 해보겠습니다.
public class TestBuilderPattern {
public static void main(String[] args) {
Computer com1 = new Computer.ComputerBuilder("500 GB", "2 GB")
.setBluetoothEnabled(true)
.setGraphicsCardEnabled(true).build();
//블루투스랑 그래픽카드를 사용하지 않으면 이렇게 만든다.
Computer com2 = new Computer.ComputerBuilder("1 TB" , "16 GB")
.build();
}
}
아 💢 필드가 너무 많아요 언제 다 만들어요? 🤬
만약 Computer 객체에 다음과 같이 선택적 필드가 엄청 많다면 코드량이 늘어나게 됩니다. 하지만 이런 방법을 해결해주기 위해 Lombok 이 있습니다.
Lombok을 설치하시고 라이브러리를 넣어주시면 됩니다.(다른 블로그를 참조해주세요.)
ComputerLombok.class
@Builder
@Getter
public class ComputerLombok {
//required
private String HDD;
private String RAM;
//optional
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;
}
해당 클래스에 @Builder 어노테이션만 붙여주면 Lombok이 알아서 만들어줍니다.
@Getter 어노테이션은 모든 필드에 관한 getter 메소드를 만들어주는 작업을 해줍니다.
이렇게 만드시면 코드량이 엄청 줄게 됩니다.