본문 바로가기
SW

GoF의 디자인 패턴(Design Patterns: Elements of Reusable Object-Oriented Software) - 3장 생성 패턴 :: 빌더(Builder)

by 라꾸스떼(YR) 2020. 4. 19.
반응형

[빌더(Builder) - 객체 생성]

<의도>

복잡한 객체를 생성하는 방법과 표현하는 방법을 정의하는 클래스를 별도로 분리하여, 서로 다른 표현이라도 이를 생성할 수 있는 동일한 절차를 제공할 수 있도록 한다.

 

<동기>

각 변환기(converter) 클래스들은 복잡한 객체를 생성하고 조립하는 데 필요한 메커니즘을 Converter 클래스에 정의된 인터페이스의 각 연산에 구현한다. 이러한 변환기를 판독기와 분리시켜서, 판독기는 RTF 문서의 책임만 지게 하자는 것이다.

빌더 패턴은 이런 문제를 푸는 데 쓴다. 지금까지 등장한 각 변환기 클래스들이 바로 빌더 패턴에서 쓰는 용어인 "빌더"이다. 그리고 판독기는 디렉터(director)라 한다.

 

<활용성>

-복합 객체의 생성 알고리즘이 이를 합성하는 요소 객체들이 무엇인지 이들의 조립 방법에 독립적일 때

-합성할 객체들의 표현이 서로 다르더라도 생성 절차에서 이를 지원해야할 때

 

<참여자>

-Builder : Product 객체의 일부 요소들을 생성하기 위한 추상 인터페이스를 정의한다.

-ConcreteBuilder : Builder클래스에 정의된 인터페이스를 구현하며, 제품의 부품들을 모아 빌더를 복합한다. 생성한 요소의 표현을 정의하고 관리하며 제품을 검색하는 데 필요한 인터페이스를 제공한다.

-Director : Builder 인터페이스를 사용하는 객체를 합성한다.

-Product : 생성할 복합 객체를 표현한다. ConcreteBuilder는 제품(product)의 내부 표현을 구축하고 복합 객체가 어떻게 구성되는지에 관한 절차를 정의한다.

 

<협력 방법>

-사용자는 Director 객체를 생성하고, 이렇게 생성한 객체를 자신이 원하는 Builder 객체로 합성해 나간다.

-제품의 일부가 구축될 때마다 Director는 Builder에 통보한다.

-Builder는 Director의 요청을 처리하여 제품에 부품을 추가한다.

-사용자는 Builder에서 제품을 검색한다.

 

<결과>

1.제품에 대한 내부 표현을 다양하게 변화할 수 있다. Builder 객체는 디렉터를 제공하고 제품을 복합하기 위해 필요한 추상 인터페이스를 정의한다. 빌더를 제공하면 제품이 어떤 요소에서 복합되는지, 그리고 각 요소들의 표현 방법이 무엇인지 가릴 수 있게 된다. 새로운 제품의 표현 방법이나 제품의 복합 방법이 바뀔 때 추상 인터페이스를 정의한 Builder 클래스에서 상속을 통해 새로운 서브클래스를 정의하면 된다.

2.생성과 표현에 필요한 코드를 분리한다. 빌더 패턴을 사용하면, 복합 객체를 생성하고 복합 객체의 내부 표현 방법을 별도의 모듈로 정의할 수 있다. 사용자는 제품의 내부 구조를 정의한 클래스는 전혀 모른 채, 빌더와 상호작용을 통해서 필요한 복합 객체를 생성하게 된다. 각 ConcreteBuilder는 특정 종류의 제품을 생성하고 조립하는 데 필요한 모든 코드를 포함한다. Director 객체들이 이것을 재사용해서 똑같은 부품에서 여러 가지 Product를 구축할 수 있다.

3.복합 객체를 생성하는 절차를 좀더 세밀하게 나눌 수 있다. 한번에 복합 객체를 생성하는 것처럼, 빌더 패턴ㅇ느 디렉터의 통제 아래 하나씩 내부 구성요소들을 만들어 나간다. 디렉터가 빌더에서 만든 전체 복합 객체를 되돌려받을 때까지 제품 복합의 과정은 계속된다.

 

<구현>

추상 클래스인 Builder 클래스에 디렉터가 요청하는 각각의 요소들을 생성하는 연산들을 정의한다. 기본적으로 여기 정의된 연산은 아무것도 구현되지 않은 단순한 인터페이스일 뿐이다. 이 클래스를 상속하는 서브클래스 ConcreteBuilder가 자신에게 필요한 요소를 생성하도록 부모 클래스의 연산을 재정의한다.

1.조합과 구축에 필요한 인터페이스를 정의한다. 설계할 때 중요하게 생각해야 하는 것은 생성과 조합을 위한 모델 구축이다. 구축해 달라고 하는 요청이 오면, 요소를 제품에 단순하게 추가하는 식으로 모델을 구축하는 것으로 충분하다. 간혹, 이미 구축된 제품의 부분에 대하 접근이 필요할 때가 있다.

2.제품에 대한 추상 클래스는 필요 없는가? 일반적으로 제품은 상세화된 Builder 클래스의 서브클래스로 생성되는데, 제품마다 그 제품을 표현하는 방법이 다르고 이것에서 어떠한 공통점도 찾을 수 없기 때문에, 서로 다른 제품에 공통적인 기본 클래스를 준다고 해서 얻을 게 별로 없다. 사용자는 데릭터를 만들 때 적당한 빌더를 제공하게 되고, 이 Builder의 서브클래스를 이용해서 적당한 제품을 만들고 다룰 수 있게 된다.

3.Builder에 있는 메서드에 대해서는 구현을 제공하지 않는 게 일반적이다. C++로 구현할 때는, 빌더에 정의된 메서드를 의도적으로 가상 함수로 정의하지 않는다. 서브클래스에서 모든 가상 함수가 아니고 필요한 메서드만 재정의하기 위해서이다.

 

<예제 코드>

다른 생성 패턴과 마찬가지로 빌더 패턴은 객체가 어떻게 생성되는지를 캡슐화한다.

 

<잘 알려진 사용예>

-

 

<관련 패턴>

복잡한 객체를 생성해야 할 때 추상 팩토리 패턴은 빌더 패턴과 비슷한 모습을 보인다. 근본적인 차이가 있다면 빌더 패턴은 복잡한 객체의 단계별 생성에 중점을 둔 반면, 추상 팩토리 패턴은 제품의 유사군들이 존재할 때 유연한 설계에 중점을 둔다는 것이다. 빌더 패턴은 생성의 마지막 단계에서 생성한 제품을 반환하는 반면, 추상 팩토리 패턴에서는 만드는 즉시 제품을 반환한다.

반응형

댓글