2

我正在实现一个 Builder 构造函数,如 Joshua Bloch 的“Effective Java 2nd Edition”中所述。但是,当我尝试扩展类及其构建器时,我遇到了一些复杂情况。本质上,扩展子类中的扩展 Builder 有设置返回父构建器类型而不是子构建器类型的字段方法。

当然,我可以在属性构建链中回滚到 ChildBuilder(如我的 main 方法中所示),但它不是无缝的,这违背了 Builder 的目的,它也迫使我分离父 setter 和子 setter。

我尝试使用泛型,但它最终变得比演员更冗长。

有没有一种方法可以让构建器上的 set 方法始终返回实际实例化的构建器类型?

public class ParentObj {

    public static void main(String[] args) { 

    ChildObj childObj = ((ChildObj.ChildBuilder) (new ChildObj.ChildBuilder())
                .prop1(11)
                .prop2(21)
                .prop3(14))
                .prop4(12)
                .prop5(33)
                .build();
    }



    private int prop1;
    private int prop2;
    private int prop3;

    protected ParentObj(Builder builder) {
        this.prop1 = builder.prop1;
        this.prop2 = builder.prop2;
        this.prop3 = builder.prop3;
    }

    public class Builder { 
        private int prop1;
        private int prop2;
        private int prop3;
        public Builder prop1(int prop1) { this.prop1 = prop1; return this; } 
        public Builder prop2(int prop2) { this.prop2 = prop2; return this; } 
        public Builder prop3(int prop3) { this.prop3 = prop3; return this; } 

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

    }

    private class ChildObj extends ParentObj { 

    private final int prop4;
    private final int prop5;

    private ChildObj(ChildBuilder childBuilder) {
        super(childBuilder);

    }

    public class ChildBuilder extends Builder {
        private int prop4;
        private int prop5; 
        public ChildBuilder prop4(int prop4) { this.prop4 = prop4; return this; } 
        public ChildBuilder prop5(int prop5) { this.prop5 = prop5; return this; } 

        public ChildObj build()  { 
            return new ChildObj(this);
        }
    }
}
4

1 回答 1

1

可能最好的方法是覆盖父构建器方法。

class ChildBuilder {
  public ChildBuilder prop1(int prop1){ 
    return (ChildBuilder) super.prop1(prop1);
  }
}

虽然这并不完全干净,但它适用于您正在尝试做的事情。

于 2014-06-30T18:01:05.403 回答