study/design pattern

[DESIGN PATTERN] 빌더 패턴

자바왕세자 2020. 8. 30. 17:42

빌더 패턴

필드가 많은 객체를 생성할 경우 생성자를 이용하면 다루기도 어렵고 헷갈릴 수도 있다.

@Getter @Setter
public class Computer {
    private String HDD;
    private String RAM;
    private String graphicCard;
    private String CPU;

    private boolean isGraphicCardEnable;
    private boolean isBluetoothEnable;
}

이 필드 중에는 객체로 생성할 때 꼭 포함되어야 하는 필드도 있고 그렇지 않은 필드도 있다.

꼭 포함되어야 하는 필드들은 생성자의 매개변수로 꼭 포함이 되어있어야 한다.

꼭 포함되어야 하는 필드들이 많아질수록 생성자는 그만큼 복잡해진다.

또 각 필드마다 자리가 정해져있기 때문에 순서도 맞춰서 생성자로 값을 주입해주어야 하는 불편함도 생긴다.

public Computer(String HDD, 
                String RAM, 
                String graphicCard, 
                String CPU, 
                boolean isGraphicCardEnable, 
                boolean isBluetoothEnable) {
        this.HDD = HDD;
        this.RAM = RAM;
        this.graphicCard = graphicCard;
        this.CPU = CPU;
        this.isGraphicCardEnable = isGraphicCardEnable;
        this.isBluetoothEnable = isBluetoothEnable;
}

 

이런 상황에서 도움이 되는 것이 빌더 패턴이다.

빌더 패턴을 사용하면 도메인에 적합한 객체를 생성하는 빌더라는 동반자 객체를 만들 수 있다.

@Getter @Setter
public class Computer {

    private String HDD;
    private String RAM;
    private String graphicCard;
    private String CPU;

    private boolean isGraphicCardEnable;
    private boolean isBluetoothEnable;

    private Computer(Builder builder) {
        this.HDD = builder.HDD;
        this.RAM = builder.RAM;
        this.graphicCard = builder.graphicCard;
        this.CPU = builder.CPU;
        this.isGraphicCardEnable = builder.isGraphicCardEnable;
        this.isBluetoothEnable = builder.isBluetoothEnable;
    }

    public static class Builder{
        private String HDD;
        private String RAM;
        private String graphicCard;
        private String CPU;

        private boolean isGraphicCardEnable;
        private boolean isBluetoothEnable;

        public Builder(String HDD, String RAM){
            this.HDD = HDD;
            this.RAM = RAM;
        }

        public Builder graphicCard(String graphicCard){
            this.graphicCard = graphicCard;
            return this;
        }

        public Builder CPU(String CPU){
            this.CPU = CPU;
            this.isGraphicCardEnable = true;
            return this;
        }

        public Builder bluetooth(boolean isBluetoothEnable){
            this.isBluetoothEnable = isBluetoothEnable;
            return this;
        }

        public Computer build(){
            return new Computer(this);
        }


    }
}

 

위 코드를 보면 Computer 클래스의 생성자가 private로 설정되어 있는 것을 볼 수 있다.

Computer 클래스는 builder를 통해서만 생성자에 접근할 수 있다는 것을 보여준다.

아래는 직접 구현한 빌더 클래스를 사용하는 예제이다.

public static void main(String[] args) {
        Computer computer = new Computer.Builder("500GB", "2GB")
                .bluetooth(true)
                .CPU("i5")
                .graphicCard("GTX")
                .build();

        System.out.println(computer.getCPU());
        System.out.println(computer.getGraphicCard());
        System.out.println(computer.isGraphicCardEnable());
}


//결과
i5
GTX
true

 

 

정리

빌더 패턴은 객체 생성을 깔끔하게, 그리고 유연하게 할 수 있도록 도와준다.

생성자 인자가 많을 경우에는 빌더 패턴을 사용하는 것이 더 편리하다.

lombok에서 @Builder라는 어노테이션을 제공하고 있어서 생성자나 클래스에 @Builder 어노테이션을 명시해주면

어노테이션이 명시된 범위에 해당하는 만큼 빌더 클래스를 자동으로 제공해준다.