빌더 패턴에 관해서는 이펙티브 자바의 내용을 한번더 참고하자.
Motivation
애플리에키션이 복잡하다는 것은 클래스와 객체가 복잡하는 것이다. 복잡한 객체는 생성할때 실수를 줄이자!
Intent
- 객체 생성을 위한 인스턴스를 만들자!
- 근데 어떤 클래스를 만들지는 subclasses가 결정하게 할거임
- 공통 인터페이스를 통해 새롭게 생성된 객체를 참조하자! (????)
Implementation
빌더 패턴은 어떤 구체 클래스를 만들지에 대해서는 팩토리 빌더 패턴을 사용한다.

Builder
- Product 객체 생성에 대한 interface를 제공함
ConcreteBuilder
- Builder 인터페이스를 구현해서 직접 Product를 생성하는 인터페이스를 제공함
Director
- Builder 인터페이스를 써서 Product 객체를 만들어 사용함
Product
- 빌더를 통해 생성되는 복잡한 객체

Code Example
//Abstract Builder class abstract class TextConverter{ abstract void convertCharacter(char c); abstract void convertParagraph(); } // Product class ASCIIText{ public void append(char c){ //Implement the code here } } //Concrete Builder class ASCIIConverter extends TextConverter{ ASCIIText asciiTextObj;//resulting product /*converts a character to target representation and appends to the resulting*/ void convertCharacter(char c){ char asciiChar = new Character(c).charValue(); //gets the ascii character asciiTextObj.append(asciiChar); } void convertParagraph(){} ASCIIText getResult(){ return asciiTextObj; } } //This class abstracts the document object class Document{ static int value; char token; public char getNextToken(){ //Get the next token return token; } } //Director class RTFReader{ private static final char EOF='0'; //Delimitor for End of File final char CHAR='c'; final char PARA='p'; char t; TextConverter builder; RTFReader(TextConverter obj){ builder=obj; } void parseRTF(Document doc){ while ((t=doc.getNextToken())!= EOF){ switch (t){ case CHAR: builder.convertCharacter(t); case PARA: builder.convertParagraph(); } } } } //Client public class Client{ void createASCIIText(Document doc){ ASCIIConverter asciiBuilder = new ASCIIConverter(); RTFReader rtfReader = new RTFReader(asciiBuilder); rtfReader.parseRTF(doc); ASCIIText asciiText = asciiBuilder.getResult(); } public static void main(String args[]){ Client client=new Client(); Document doc=new Document(); client.createASCIIText(doc); System.out.println("This is an example of Builder Pattern"); } }
일반적으로 사용하는 filed를 하나씩 지정해주는 static class를 가진 빌더가 아니다... (← 사실 이건 빌더 패턴이 아닌가?)
그리고 타겟 객체인 ASCIIText도 그리 복잡해 보이지 않는다. 하지만 디자인 패턴에서 가장 중요한 것은 코드의 구조가 아니라 Intent라는 것을 명심하자.
Applicablity
빌더 패턴은 이럴때 쓰자
- 객체가 가진 (has -a) 필드의 생성과는 독립적으로 자기 자신의 생성 로직이 복잡할때
- 생성 로직을 객체와 분리하고 싶을때
Examples
우리가 Vehicle 제조업체라고 생각해보자
우리는 부품을 조합해서 차도 만들고 자전거도 안들고 스쿠터도 만들고 오토바이도 만들 수 있다.
모든 Vehicle이 사용하는 부품을 조합해서 만들 수 있는 부분을 VehicleBuilder로써 Interface로 제공할 수 있고 각각의 차량 타입에 대해서 필요한 부품만을 추가하는 ConcreteBuilder를 만들어 다양한 Vehicle의 제조를 편리하게 할 수 있다.
Specific problems
빌더 패턴 vs 추상 팩토리 패턴
- 추상 팩토리 패턴
- Client는 공장이 찍어주는 것 밖에 못씀
- 추상 팩토리 패턴을 사용하면 무조건 공장의 공장을 만들기 때문에 추상 팩토리를 만들어야함
- 빌더 패턴
- Client는 직접 Builder의 조합을 요청 할 수 있음
- 여러 공통된 역할의 타입을 제공할 필요가 없다면 추상 빌더를 제공할 필요 없음