Java:生成器,继承,泛型Redux

老乌龟

我需要创建一组通过多级层次结构继承的Builder类,从而使Builders既要驻留在要构建的类之外,也要驻留在其他包中。

从此示例走出去:https : //onelostlogician.wordpress.com/2016/10/10/inheritance-generics-and-builders/以下代码是通过根据要求进行更改而创建的:1.将构建者移至顶层, 2.将构建器和待构建对象放入不同的程序包中,并在后者中添加设置器,3.将静态newXYZ()方法移至构建器中,并删除其类型参数以消除擦除冲突。这将是所需产品的合适模型。

package other;

public abstract class BaseClass {
    protected Integer field1;

    BaseClass () {
    }

    public Integer getField1 () {
        return field1;
    }

    public void setField1 (Integer field1) {
        this.field1 = field1;
    }
}

package my;

import other.BaseClass;

public abstract class BaseClassBuilder<T extends BaseClass, BU extends BaseClassBuilder> {
    protected T obj;

    protected BaseClassBuilder (T obj) {
        this.obj = obj;
    }

    protected final BU getThis () {
        return (BU) this;
    }

    public BU withField1 (Integer field1) {
        obj.setField1(field1);
        return getThis();
    }

    public T build () {
        return this.obj;
    }
}

package other;

import java.util.UUID;

public class SubClass extends BaseClass {
    protected UUID field2 = null;

    public SubClass () {
    }

    public UUID getField2 () {
        return field2;
    }

    public void setField2 (UUID field2) {
        this.field2 = field2;
    }
}

package my;

import java.util.UUID;

import other.SubClass;

public class SubClassBuilder<T extends SubClass, BU extends SubClassBuilder> extends BaseClassBuilder<T, BU> {
    protected SubClassBuilder (T obj) {
        super(obj);
    }

    public BU withField2 (UUID field2) {
        obj.setField2(field2);
        return getThis();
    }

    public T build () {
        return this.obj;
    }

    public static SubClassBuilder neu () {
        return new SubClassBuilder<>(new SubClass());
    }
}

package other;

public class SubSubClass extends SubClass {
    protected String field3 = null;

    public SubSubClass () {
    }

    public String getField3 () {
        return field3;
    }

    public void setField3 (String field3) {
        this.field3 = field3;
    }
}

package my;

import other.SubSubClass;

public class SubSubClassBuilder<T extends SubSubClass, BU extends SubSubClassBuilder<T, BU>> extends SubClassBuilder<T, BU> {
    protected SubSubClassBuilder (T obj) {
        super(obj);
    }

    public BU withField3 (String field3) {
        obj.setField3(field3);
        return getThis();
    }

    public T build () {
        return this.obj;
    }

    public static SubSubClassBuilder neu () {
        return new SubSubClassBuilder<>(new SubSubClass());
    }
}

结果:SubSubClassBuilder.neu()。withField1(..)返回BaseClassBuilder,withField2(..)返回SubClassBuilder,如Android Studio 3.0.1中每个代码完成所示。在每个构建器中重写getThis()也不起作用。

回到第一个方框,我想念什么?

编辑:遵循Java的提示:构建器模式,继承和泛型,还尝试使用静态(内部)构建器类,但效果相同:

    package my;

    import java.util.UUID;

    import other.BaseClass;
    import other.SubClass;
    import other.SubSubClass;

    public class Builders {

        private Builders () {}

        abstract static class BaseClassBuilder<T extends BaseClass, BU extends BaseClassBuilder> {
            protected T obj;

            protected BaseClassBuilder (T obj) {
                this.obj = obj;
            }

            protected final BU getThis () {
                return (BU) this;
            }

            public BU withField1 (Integer field1) {
                obj.setField1(field1);
                return getThis();
            }

            public T build () {
                return this.obj;
            }
        }

        public static class SubClassBuilder<T extends SubClass, BU extends SubClassBuilder> extends BaseClassBuilder<T, BU> {
            protected SubClassBuilder (T obj) {
                super(obj);
            }

            public BU withField2 (UUID field2) {
                obj.setField2(field2);
                return getThis();
            }

            public T build () {
                return this.obj;
            }

            public static SubClassBuilder neu () {
                return new SubClassBuilder<>(new SubClass());
            }
        }

        public static class SubSubClassBuilder<T extends SubSubClass, BU extends SubSubClassBuilder<T, BU>> extends SubClassBuilder<T, BU> {
            protected SubSubClassBuilder (T obj) {
                super(obj);
            }

            public BU withField3 (String field3) {
                obj.setField3(field3);
                return getThis();
            }

            public T build () {
                return this.obj;
            }

            public static SubSubClassBuilder neu () {
                return new SubSubClassBuilder<>(new SubSubClass());
            }
        }
    }
Bowmore

好消息:可以做到。使您的方法无法实现的原因是,您希望中​​间构建器子类既可以具体化自己的自身类型,又可以通过子类对其进行扩展。事实证明这是不可能的。

为了使其正常工作,您必须在每个级别上都有一个抽象子类,该子类添加必要的方法并允许进一步扩展子类型,以及一个将其自身指定为特定生成器的具体子类。

类图

这是我改编的实现:

首先,基类。我所做的更改主要是在构造函数中传递self类型的类。

portected abstract class BaseClassBuilder<T extends BaseClass, BU extends BaseClassBuilder<T, BU>> {
    protected T obj;
    private BU self;

    protected BaseClassBuilder (T obj, Class<?> selfType) {
        this.obj = obj;
        this.self = (BU) selfType.cast(this);
    }

    final BU getThis () {
        return self;
    }

    public BU withField1 (Integer field1) {
        obj.setField1(field1);
        return getThis();
    }

    public T build () {
        return this.obj;
    }
}

现在为的抽象版本SubClassBuilder此代码添加了构建实例所需的所有方法SubClass,但仍然是抽象的,因此仍可以扩展。

public abstract class AbstractSubClassBuilder<T extends SubClass, BU extends AbstractSubClassBuilder<T, BU>> extends BaseClassBuilder<T, BU> {

    protected AbstractSubClassBuilder(T obj, Class<?> selfType) {
        super(obj, selfType);
    }

    public BU withField2 (UUID field2) {
        obj.setField2(field2);
        return getThis();
    }
}

这使我们可以SubClass很容易地实例创建一个具体的构建器类

public final class SubClassBuilder extends AbstractSubClassBuilder<SubClass, SubClassBuilder> {

    private SubClassBuilder(SubClass obj) {
        super(obj, SubClassBuilder.class);
    }

    public static SubClassBuilder neu () {
        return new SubClassBuilder(new SubClass());
    }
}

下一级别的工作原理相同。一个抽象类,用于添加其他构建器方法,并允许进一步扩展,它扩展了AbstractSubClassBuilder

public class AbstractSubSubClassBuilder<T extends SubSubClass, BU extends AbstractSubSubClassBuilder<T, BU>> extends AbstractSubClassBuilder<T, BU> {

   protected AbstractSubSubClassBuilder (T obj, Class<BU> selfType) {
        super(obj, selfType);
    }

    public BU withField3 (String field3) {
        obj.setField3(field3);
        return getThis();
    }
}

使它具体化,需要另一个类,但是现在静态工厂方法不会从其父类中隐藏一个(neu:您是德国人吗?)

public class SubSubClassBuilder extends AbstractSubSubClassBuilder<SubSubClass, SubSubClassBuilder> {

    private SubSubClassBuilder(SubSubClass obj) {
        super(obj, SubSubClassBuilder.class);
    }

    public static SubSubClassBuilder neu () {
        return new SubSubClassBuilder(new SubSubClass());
    }
}

现在,构建这两个类的实例都非常容易。

SubSubClass subSubClass = SubSubClassBuilder.neu()
        .withField2(UUID.randomUUID())
        .withField1(5)
        .withField3("3")
        .build();

SubClass subClass = SubClassBuilder.neu()
        .withField1(66)
        .withField2(UUID.randomUUID())
        .build();

贷给AssertJ,我首先看到它完成了)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章