공부/디자인 패턴

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

감자 바보 2022. 3. 25. 17:53
반응형

빌더 패턴 (Builder Pattern)

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

 

활용

  • 객체 생성 알고리즘이 조립 방법에 독립적인 경우
  • 합성할 객체 표현이 다르더라도 생성 절차에서 표현 과정을 지원해야하는 경우

장점

  • 제품 내부 표현 다양화
  • 생성과 표현 코드 분리
  • 복합 객체 생성 절차의 세밀화

구조

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

ConcreateBuilder: Builder에 정의된 인터페이스 구현, 제품(Product) 구현 및 제공

Director: 제품 생성 절차를 담당하며 필요에 따라 Builder 인터페이스를 요청하여 제품 생성

Product: 생성된 복합 객체

 

예시


UML

PhoneBuilder는 객체 생성을 위한 작업들이 정의 되어있고 Director에선 객체 생성 절차에 따라 PhoneBuilder의 생성 작업을 호출한다. 그 결과 생성되는 Phone 객체를 반환한다.

 

코드

Display와 InnerDevice 코드는 링크에서 확인할 수 있다.

 

Phone.java

더보기
public class Phone {
    private Display display;
    private InnerDevice innerDevice;

    public void setDisplay(Display display) {
        this.display = display;
    }

    public Display getDisplay() {
        return display;
    }

    public void setInnerDevice(InnerDevice innerDevice) {
        this.innerDevice = innerDevice;
    }

    public InnerDevice getInnerDevice() {
        return innerDevice;
    }
}

PhoneBuilder.java

더보기
public class PhoneBuilder {
    protected Phone phone;

    public PhoneBuilder() {}
    public void BuildPhone() {}
    public void BuildInnerDevice() {}
    public void BuildDisplay() {}
}

class ApplePhoneBuilder extends PhoneBuilder {
    public ApplePhoneBuilder() {}

    @Override
    public void BuildPhone() {
        this.phone = new Phone();
    }
    @Override
    public void BuildInnerDevice() {
        this.phone.setInnerDevice(new AppleInnerDevice());
    }
    @Override
    public void BuildDisplay() {
        this.phone.setDisplay(new AppleDisplay());
    }
    public Phone GetResult() {
        return phone;
    }
}

class SamsungPhoneBuilder extends PhoneBuilder {
    public SamsungPhoneBuilder() {}

    @Override
    public void BuildPhone() {
        this.phone = new Phone();
    }
    @Override
    public void BuildInnerDevice() {
        this.phone.setInnerDevice(new SamsungInnerDevice());
    }
    @Override
    public void BuildDisplay() {
        this.phone.setDisplay(new SamsungDisplay());
    }
    public Phone GetResult() {
        return phone;
    }
}

TestBulderPattern.java

더보기
public class TestBuilderPattern {
    public static void main(String[] args) {
        Phone apple = CreateApplePhone();
        Phone samsung = CreateSamsungPhone();

        apple.getDisplay().testDisplay();
        apple.getInnerDevice().testMicrophoneInput();
        apple.getInnerDevice().testKeyboardInput();

        samsung.getDisplay().testDisplay();
        samsung.getInnerDevice().testKeyboardInput();
        samsung.getInnerDevice().testMicrophoneInput();
    }
    public static Phone CreateApplePhone() {
        ApplePhoneBuilder phoneBuilder = new ApplePhoneBuilder();
        phoneBuilder.BuildPhone();
        phoneBuilder.BuildDisplay();
        phoneBuilder.BuildInnerDevice();
        return phoneBuilder.GetResult();
    }
    public static Phone CreateSamsungPhone() {
        SamsungPhoneBuilder phoneBuilder = new SamsungPhoneBuilder();
        phoneBuilder.BuildPhone();
        phoneBuilder.BuildDisplay();
        phoneBuilder.BuildInnerDevice();
        return phoneBuilder.GetResult();
    }
}

 

마무리


 생성 패턴 중 하나인 빌더 패턴에 대해 학습하였다. 추상 팩토리 패턴과 비슷한 모습을 보이지만 빌더 패턴은 복잡한 객체의 단계별 생성을 중줌으로 한 반면 추상 팩토리 패턴은 제품의 유사군 존재 시 유연한 설계에 중점을 둔 패턴이다. 또 빌더 패턴은 생성의 마지막 단계에서 생성한 제품을 반환하지만 추상 팩토리 패턴에서는 만드는 즉시 제품을 반환한다.


참고

에릭 감마, 리처드 헬름, 랄프 존슨, 존 블리시디스, 『GoF의 디자인 패턴』, 프로텍 미디어, 2015

[Design Pattern] GoF 생성 패턴 - 빌더 패턴(Builder Pattern) - HERSTORY (4z7l.github.io)