Table of Contents
[GoF 디자인 패턴] 빌더 (Builder) 패턴
빌더 (builder) 패턴
생성(Creational) 패턴 중 하나로 복잡한 객체의 생성 과정과 표현 방법을 분리하여, 서로 다른 표현이더라도 동일한 절차로 생성하는 방법을 제공한다.
객체를 생성하는 과정이 복잡할 때 깔끔하게 관리할 수 있고, 객체를 생성할 때 필요한 데이터만을 골라 호출할 수 있다.
![image](/images/gof-design-pattern-builder/1.png)
빌더 패턴 구성요소
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 클래스에서 생성한 객체의 구성 과정을 제어하고, 원하는 객체를 생성하기 위한 구성 과정을 통일적으로 관리하는 역할을 수행한다.”
빌더 패턴 고려사항
빌더 패턴은 복잡한 객체 생성을 단순화하고 객체의 속성을 분리하여 생성할 수 있기 때문에 유연하다.
객체의 속성이 많거나 객체 생성 과정에서 유연성이 요구되는 경우, 객체 생성 과정이 복잡할 때 빌더 패턴을 고려해 볼 수 있다.
빌더 패턴 적용 시 장점
- 객체의 생성 과정이 복잡할 때 코드 가독성을 높여준다.
- 생성 과정에서 필요한 변수를 명확하게 구분할 수 있어 생성 과정의 오류를 줄여준다.
- 생성 과정에서 다양한 타입의 객체를 생성할 수 있어서 유연성이 높아진다.
빌더 패턴 적용 시 단점
- 생성 과정이 복잡한 객체를 생성할 때 구조가 복잡해질 수 있다.
- 객체 생성 과정에서 필요한 변수가 많아질 경우 Builder 클래스의 코드가 복잡해질 수 있다.
- 객체의 상태를 변경할 때 마다 새로운 객체를 생성하게 되어 성능이 저하될 수 있다.