2015-01-16 1 views
6

"효과적인 Java"에서 다루는 "작성자 패턴"에 관한 질문이 있습니다. 패턴을 올바르게 구현하려면 .build() 메서드가 필요합니까?작성자 패턴에 .build() 메소드가 필요합니까?

public class CoffeeDrink { 

    private int numEspressoShots; 
    private short milkType; 
    private boolean withWhip; 

    private CoffeeDrink() { 
    } 

    public static CoffeeDrink buildNewDrink() { 
     return new CoffeeDrink(); 
    } 

    public CoffeeDrink withEspresso(int n) { 
     this.numEspressoShots = n; 
     return this; 
    } 

    public CoffeeDrink withMilkType(shot t) { 
     this.milkType = t; 
     return this; 
    } 

    public CoffeeDrink withWhip() { 
     this.withWhip = true; 
     return this; 
    } 
} 

그리고 우리가 그것을 사용하는 방법 : 나는 정적 내부 Builder 클래스가없는 경우

CoffeeDrink c = CoffeeDrink.buildNewDrink() 
         .withEspresso(2) 
         .withMilkType(2) 
         .withWhip(); 

이 여전히 유효겠습니까 예를 들어, 우리는 다음과 같은 클래스가 있다고 가정 해 봅시다? 이점 중 하나는 메서드 .build()이 호출 될 때까지 새로운 CoffeeDrink 개체를 만드는 것을 보류하고 있지만 여전히 Builder 개체를 생성하고 있다는 것입니다. 그냥 몇 가지 설명을 구하십시오.

+1

빌더 패턴 불변 클래스에 큰 장점을 사용한다. 그들과 함께 빌더는 최종 제품의 궁극적 인 구성을 지원하는 가변적 인 "도우미"클래스이며 이후에는 변경되지 않습니다. 귀하의 예제는 단순한 POJO 일 뿐이며 JavaBeans의 단점 (변경 가능, 불완전하거나 일관성없는 상태에서 볼 수 있음 등)을 공유합니다. – scottb

답변

14

아니요, 이것은 작성자 패턴이 아닙니다. 그것은 유효한 자바이고 컴파일되고 실행됩니다. 그러나 귀하의 buildNewDrink() 방법은 build() 또는 buildNewDrink() 또는 다른 어떤 것이 든 상관없이 CoffeeDrink을 생성하는 간단한 공장 방법입니다. 다른 방법은 스스로를 반환하는 세터 메소드와 같습니다.

static 중첩 된 빌더 클래스가 필요합니다. 클래스 인스턴스 작성을 보류하는 동안 유효성 검증 논리를 수행하여 유효하지 않은 오브젝트가 작성되지 않도록 할 수 있습니다. 나는 당신이 가지고있는 것처럼 CoffeeDrink에 무효 상태가 있다는 것을 확신하지 못한다. 그러나 그랬다면, 코드와 함께 CoffeeDrink을 생성 할 수 있었고, 그것이 생성 된 이후에는 유효하지 않은 상태가 될 수있다. 다른 메소드가 호출되었습니다. 빌더 패턴은 인스턴스를 빌드하기 전에 데이터의 유효성을 검사하여 이러한 가능성을 없애줍니다. 또한 모든 가능한 경우를 다루기 위해 모든 가능한 매개 변수 조합이 필요한 많은 생성자가 필요한 생성자 폭발의 필요성을 없애줍니다.

+0

나는 귀하의 의견에 동의합니다. 이 메소드는 * chaining *을 가진 정규 setter 인 것처럼 보입니다. 단지 사소한 부분이지만, "유효하지 않은 객체가 ** 생성되지 않았는지 확인하는 검증 로직을 ** 수행 할 수 있습니다"*와 같이 대답에 * "not"*가 누락 될 수 있습니다 *. – afsantos

+0

@afsantos 감사합니다; 수정 됨. – rgettman

+0

설명 주셔서 감사합니다. 그렇다면 CoffeeDrink 인스턴스를 반환하기 전에 Builder 클래스의 빌더 함수에서 모든 매개 변수의 유효성을 검사합니까? – victormejia

1

GoF 참조에 따르면 build()은 필요하지 않습니다. 원래 참조는 연결을 사용하지 않으며 Director.construct() 메서드 끝에 getResult() 단계가 있습니다. Director 클래스는 빌드 프로세스 캡슐화를 담당하므로 올바르게 빌드하면 걱정할 필요가 없습니다. Director의 책임입니다.

여기 작성기 GoF의 기준의 시퀀스 다이어그램이다 :

GoF Builder Sequence Diagram

관련 문제