Используя конструктор Builder в расширенном классе?

Я реализую конструктор Builder, как описано в "Effective Java 2nd Edition" Джошуа Блоха. Однако при попытке расширить класс и его построителя у меня возникают некоторые сложности. По сути, расширенный Builder в расширенном дочернем классе имеет Установите методы поля, которые возвращают родительский тип Builder, а не дочерний тип Builder.

Конечно, я могу привести к ChildBuilder в цепочке сборки свойств (как показано в моем основном методе), но это не является бесшовным, что противоречит цели Builder, и это также заставляет меня разделять родительские и дочерние сеттеры.

Я пытался использовать дженерики, но в итоге он стал более многословным, чем актеры.

Есть ли способ, которым я могу последовательно заставить методы 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);
        }
    }
}

1 ответ

Решение

Вероятно, лучшим способом было бы переопределить родительские методы компоновщика.

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

Хотя это не совсем чисто, это сработает для того, что вы пытаетесь сделать.

Другие вопросы по тегам