2014-06-16 4 views
3

클래스 a를 aX로 확장하려고합니다. 그래서 빌더를 확장합니다. 그러나 클래스 A의 객체를 만들 수있는 동안은 다음을 사용합니다.Builder 패턴을 사용하여 클래스 확장하기

aX에는 동일하게 적용되지 않습니다. 나는이 작업을 수행 할 때 :

aXBuilder fb = new aXBuilder(); 
aX aXtry = fb.withI(i).withS(s).withB(b).build(); 

를 내가 오류 (메소드 withB (부울) 유형 a.aBuilder에 대한 정의이다). 단순히 새로운 것을 추가하는 대신 aX에 대한 모든 내용을 다시 작성해야합니까? 나는 그것이 내 코드에 많은 중복을 초래할 것이기 때문에 그렇게하고 싶지 않다. 클래스 A와 도끼가 아래에서 언급과 같이

class a { 

protected String s; 
protected int i; 

public void getdata() { 
    System.out.println(this.s); 
    System.out.println(this.i); 
} 

protected a(aBuilder fb) { 
    this.s = fb.bs; 
    this.i = fb.bi; 
} 

public static class aBuilder { 
    public aBuilder() { 
    } 

    protected String bs; 
    protected int bi; 

    public aBuilder withS(String s) { 
     this.bs = s; 
     return this; 
    } 

    public aBuilder withI(Integer i) { 
     this.bi = i; 
     return this; 
    } 

    public a build() { 
     return new a(this); 
    } 

} 

}

클래스 도끼는 방법이없는 aBuilder하는 {

protected Boolean b; 

public void getData() 
{ 
    System.out.println(this.s); 
    System.out.println(this.i); 
    System.out.println(this.b); 
} 

protected aX(aXBuilder axb) { 
    super(axb); 
    this.b = axb.bb; 
} 

public static class aXBuilder extends aBuilder { 
    protected Boolean bb; 

    public aXBuilder() { 
    } 

    public aXBuilder withB(Boolean b) { 
     this.bb = b; 
     return this; 
    }; 

    public aX build() { 
     return new aX(this); 
    } 
} 

}

+0

당신이는 그 질문을보고 있었나요? http://stackoverflow.com/questions/21086417/builder-pattern-and-inheritance and http://stackoverflow.com/questions/17164375/subclassing-a-java-builder-class? – John

답변

4

. 이 사이트에 숨어서 구체적인 수업에서 물려받은 것은 널리 악으로 간주됩니다.

public abstract class AbstractA { 
    protected String s; 
    protected int i; 
    protected AbstractA() { 
    } 
    protected abstract static class ABuilder<T extends AbstractA, B extends ABuilder<T,B>> { 
     protected T object; 
     protected B thisObject; 
     protected abstract T getObject(); //Each concrete implementing subclass overrides this so that T becomes an object of the concrete subclass 
     protected abstract B thisObject(); //Each concrete implementing subclass builder overrides this for the same reason, but for B for the builder 
     protected ABuilder() { 
      object = getObject(); 
      thisObject = thisObject(); 
     } 
     public B withS(String s) { 
      object.s = s; 
      return thisObject; 
     } 
     public B withI(int i) { 
      object.i = i; 
      return thisObject; 
     } 
     public T build() { 
      return object; 
     } 
    } 
} 

당신이 함께 귀하의 추상 클래스가 있으면 당신이 필요로하는, 당신은 단지 당신이 필요로하는 개체의 유형을 반환 빌더의 추상 메소드를 오버라이드 (override), 그것을 몇 번을 확장합니다. 그런 다음

public final class ConcreteA extends AbstractA { 
    private String foo; 
    protected ConcreteA() { 
    } 
    public static final class Builder extends AbstractA.ABuilder<ConcreteA,Builder> { 
     @Override protected ConcreteA getObject() { 
      return new ConcreteA(); 
     } 
     @Override protected Builder thisObject() { 
      return this; 
     } 
     public Builder() { 
     } 
     public Builder withFoo(String foo) { 
      object.foo = foo; 
      return this; 
     } 
    } 
} 

... ConcreteA baz = new ConcreteA.Builder().withFoo("foo").withS("bar").withI(0).build();

+0

이 방법이 효과적이지만 "ABuilder >"에서 무슨 일이 일어나는지 설명 할 수 있습니까? – hoodakaushal

+0

"해당 하위 유형에 대해서만 인스턴스화 할 수있는 유형으로서 해당 하위 유형은 일부 유용한 메소드를 상속받습니다. 일부 메소드는 하위 유형 인수를 취합니다 (그렇지 않으면 하위 유형에 종속됩니다). 이것은 [여기] (http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ106)에서 설명한대로 Enum >과 기본적으로 동일한 패턴입니다. – Q23

+0

해당 링크의 핵심 문장은 "형식 인수로 Type 열거 형의 하위 유형 만 허용됩니다."입니다. 이 경우 AbstractA의 하위 유형 만 T에 허용되고 B에 대한 AbstractA.abuilder의 하위 유형 만 허용됩니다. – Q23

0

withS(s) 반환 aBuilder을 확장 withB .

리 팩터가 필요합니다. 서브 클래스에 withS 등을 오버라이드하여 올바른 유형을 반환하십시오.

(당신은 일반적으로 명시 적으로 빌더의 인스턴스를 단지 정적 BTW을 참조,하지 않으며 또한 클래스 명 나쁜처럼)

는 추상 슈퍼 클래스의 생성을 필요로 않지만 당신은 제네릭과의 문제를 해결할 수
+0

그래서 aBuilder에서도 withB를 추가해야합니까? – hoodakaushal

+0

서브 클래스에서 오버라이드 하겠지만, 전반적인 desgin은 주관적입니다. – NimChimpsky

+0

aBuilder에 withB가없는 경우 어떻게 오버라이드 할 수 있습니까? 이거 어떻게 디자인 할 것을 제안합니까? – hoodakaushal