본문 바로가기

Design Pattern

Builder Pattern (부분 부분 생성을 통한 전체 객체 생성 문제)

 생성 패턴중 하나로써 동적으로 변환되는 객체들이 그룹으로 이루어져 있지만, 이들의 그룹화를 어떻게 진행되어야 할지 모를때 활용하면 좋다.  그리고 생성된 객체 내부에 자기가 활용하고자 하는 객체를 상황에 맞게 포함시킬때도 유용하게 적용할 수 있다. 
    빌더 객체내에서 필요한 객체를 단계별로 만들어서 필요한 객체들이 모두 생성되도록 만들고, 사용자는 이 그룹을 그냥 활용하면 된다. 

   1) 문제 사례 설명
     전세계에 수출되는 전자 제품을 만드는 회사가 있다고 하자. 이 회사에서는 여러 제품들에 대한 매뉴얼을 수출할 각 국가의 언어로 작성해야하는데 일일이 번역가에게 의뢰를 하면 시간과 비용이 너무 많이 들기 때문에 자동 번역 소프트웨어를 개발해서 메뉴얼을 제작하기로 결정하였다. 이때 개발해야 할 소프트웨어는 한국어로 된 메뉴얼을 입력하면 영어,일본어,프랑스어로 된 메뉴얼을 만들어내는 것을 목적으로 한다. 여기서 메뉴얼에 사용되는 문장은 평서문, 의문문, 명령문으로만 구성되어 있으며, 자동 번역 소프트웨어는 메뉴얼을 문장 단위로 번역하면 된다.
   -> 우리가 생성해야 할 영어, 일본어, 프랑스어로 된 메뉴얼을 각각 객체라고 해보자. 이 경우 우리가 해결해야하는 문제는 각각의 객체를 생성해주는 것이다. 그런데 여기서 메뉴얼 객체의 생성은 통상적인 객체 생성 방식과는 달리 전체 객체를 한꺼번에 생성하는 것이 아니라 메뉴얼을 구성하는 개별문장을 단위로 객체의 부분 부분을 생성한 후 이를 조합해주는 방식이어야 할 것이다. 왜냐하면 어차피 번역은 한문장씩 이루어질 것이기 때문이다.

    2) 기본적인 해결 방법 - 함수 형태 접근 방식
       한국어로 된 메뉴얼을 한 문장씩 읽어서 문장의 종류를 구분하고, 구분된 문장 종류별로 각 국가의 언어로 번역시켜주는 함수를 작성해서 사용하는 것이다. 

    3) 좀 더 나은 방식 : 전담 클래스 활용 방식
       일반 함수 형태의 접근, 즉 구조적 개념에 기반한 접근이 가지는 가장 큰 문제중 하나는 바로 요구사항의 추가, 변경시 영향을 받는 범위가 불분명하고 모듈의 재사용시에도 재사용할 모듈의 경계가 불확실하다는 것이다.
       이런 문제를 개선하기 위해서 등장한 것이 객체지향 개념에 기반한 접근방식이다. 이 방식은 명확히 구분되는 클래스를 기준으로 소프트웨어의 변경이나 재사용이 가능하게 만들어준다. 문제 해결을 위해 클래스를 활용하면 요구사항의 변화에 따라 수정할 부분이 생길 경우 그 수정 범위를 클래스 내부로 한정시킬 수 있고, 이들 모듈을 재사용하고 싶을 경우에도 클래스를 재사용의 단위로 구분지을 수 있는등의 장점을 얻게 된다. 
 
    4) Builder Pattern 활용
       클래스활용방식도 여전히 문제는 존재한다. 예를 들어 전자 제품을 수출하는 국가에 중국이 추가되었다고 하자. 이는 충분히 발생 가능한 일이며, 번역 소프트웨어는 당연히 중국어로의 번역도 추가하도록 요구받을 것이다. 그러나 중국어로의 번역을 추가하기위해서는 기존 소스코드를 일일이 분석해서 수정해야 한다는 부담이 존재한다. 즉 기존의 소스코드와는 독립적으로 중국어 번역을 추가하기가 힘들다는 것이다.
       -> 객체를 생성하되, 그 객체를 구성하는 부분 부분을 먼저 생성하고, 이를 조합함으로써 전체 객체를 생성하며, 생성할 객체의 종류가 손쉽게 추가, 확장이 가능하게 고안된 패턴이 바로 빌드 패턴이다. 

    5) 단점 : 새로운 종류의 객체 생성을 추가하기는 쉬우나, 객체를 구성하는 각 부분들을 새롭게 추가하기는 어렵다. 예를 들어 번역 소프트웨 개발에서 평서문, 의문문, 명령문만 번역하던것을 감탄문까지 번역할 수 있게 추가한다고 가정해보자. 이 경우에는 Director클래스뿐만 아니라 Translator 및 그 하위 클래스들 모두에 새로운 인터페이스를 추가하거나 수정해주어야 한다. 따라서 Builder 패턴을 적용하고자 할 경우에는 생성되는 객체를 구성하는 부분들을 명확히 해서 추가하거나 수정해야 할 부분이 없게 하는 것이 중요하다. 

    6) 구현 소스