Table of Contents

[GoF 디자인 패턴] 빌더 (Builder) 패턴

빌더 (builder) 패턴


생성(Creational) 패턴 중 하나로 복잡한 객체의 생성 과정과 표현 방법을 분리하여, 서로 다른 표현이더라도 동일한 절차로 생성하는 방법을 제공한다.

객체를 생성하는 과정이 복잡할 때 깔끔하게 관리할 수 있고, 객체를 생성할 때 필요한 데이터만을 골라 호출할 수 있다.

image

빌더 패턴 구성요소

Builder, ConcreteBuilder, Director, Product로 총 4개의 컴포넌트로 구성된다.

  • Builder : Product 객체의 일부 요소를 생성하기 위한 추상 인터페이스를 정의한다.
  • ConcreteBuilder : Builder 클래스에 정의된 인터페이스를 구현한다.
  • Director : ConcreteBuilder와 클라이언트 사이에서 중계자 역할을 수행한다.
  • Product : 생성될 대상의 객체를 나타내는 클래스이다.

구현 예제

Product 객체를 만들어준다.

 1public class Product {
 2    private String name;
 3    private int price;
 4    private String type;
 5
 6    public void setName(String name) {
 7        this.name = name;
 8    }
 9
10    public void setPrice(int price) {
11        this.price = price;
12    }
13
14    public void setType(String type) {
15        this.type = type;
16    }
17
18    @Override
19    public String toString() {
20        return "Product{" +
21                "name='" + name + '\'' +
22                ", price=" + price +
23                ", type='" + type + '\'' +
24                '}';
25    }
26}

최종적으로 만들어질 객체의 데이터 타입, 구조, 속성 등을 표현한다. 각각의 Builder는 이 Product 클래스의 객체를 생성하고, 이를 구성하는 작업을 수행한다.
“Builder 패턴의 중심이다”


Builder 클래스를 만들어준다.

 1abstract class Builder {
 2    Product product = new Product();
 3
 4    public abstract Builder buildName();
 5    public abstract Builder buildPrice();
 6    public abstract Builder buildType();
 7
 8    public Product getResult() {
 9        return product;
10    }
11}

Product 객체를 생성하고 각 구성요소의 build 메소드를 정의한다. 생성된 Product 객체를 반환하는 getResult() 메소드도 가지고 있다.
Builder 패턴의 구조만 제공하고 추상 메서드의 실제 구현과 제품 클래스는 특정 문제에 대한 요구 사항에 따라 달라질 수 있다”


ConcreteBuilder 클래스를 만들어준다.

 1public class ComputerBuilder extends Builder {
 2    @Override
 3    public Builder buildName() {
 4        product.setName("LG gram");
 5        return this;
 6    }
 7
 8    @Override
 9    public Builder buildPrice() {
10        product.setPrice(3000000);
11        return this;
12    }
13
14    @Override
15    public Builder buildType() {
16        product.setType("computer");
17        return this;
18    }
19}

Product의 다양한 요소를 조합하여 원하는 객체를 생성하기 위한 Builder 클래스의 추상 메소드를 구현한다. 생성한 객체는 Director 클래스에 의해 관리된다.
“Product 객체에 대한 구체적인 정의를 가지고 있어 객체 생성 과정을 보다 유연하게 만든다”


Director 클래스를 만들어준다.

 1public class Director {
 2    private final Builder builder;
 3
 4    public Director(Builder builder) {
 5        this.builder = builder;
 6    }
 7
 8    public Product construct() {
 9        return builder.buildName()
10                .buildPrice()
11                .buildType()
12                .getResult();
13    }
14}

클라이언트는 ConcreteBuilder 클래스의 메소드를 직접 호출하는 것이 아니라, Director 클래스를 통해 ConcreteBuilder 클래스의 construct() 메소드를 사용하여 호출하게 된다.
“ConcreteBuilder 클래스에서 생성한 객체의 구성 과정을 제어하고, 원하는 객체를 생성하기 위한 구성 과정을 통일적으로 관리하는 역할을 수행한다.”

빌더 패턴 고려사항

빌더 패턴은 복잡한 객체 생성을 단순화하고 객체의 속성을 분리하여 생성할 수 있기 때문에 유연하다.
객체의 속성이 많거나 객체 생성 과정에서 유연성이 요구되는 경우, 객체 생성 과정이 복잡할 때 빌더 패턴을 고려해 볼 수 있다.


빌더 패턴 적용 시 장점

  1. 객체의 생성 과정이 복잡할 때 코드 가독성을 높여준다.
  2. 생성 과정에서 필요한 변수를 명확하게 구분할 수 있어 생성 과정의 오류를 줄여준다.
  3. 생성 과정에서 다양한 타입의 객체를 생성할 수 있어서 유연성이 높아진다.

빌더 패턴 적용 시 단점

  1. 생성 과정이 복잡한 객체를 생성할 때 구조가 복잡해질 수 있다.
  2. 객체 생성 과정에서 필요한 변수가 많아질 경우 Builder 클래스의 코드가 복잡해질 수 있다.
  3. 객체의 상태를 변경할 때 마다 새로운 객체를 생성하게 되어 성능이 저하될 수 있다.