我需要创建一组通过多级层次结构继承的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());
}
}
}
好消息:可以做到。使您的方法无法实现的原因是,您希望中间构建器子类既可以具体化自己的自身类型,又可以通过子类对其进行扩展。事实证明这是不可能的。
为了使其正常工作,您必须在每个级别上都有一个抽象子类,该子类添加必要的方法并允许进一步扩展子类型,以及一个将其自身指定为特定生成器的具体子类。
这是我改编的实现:
首先,基类。我所做的更改主要是在构造函数中传递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] 删除。
我来说两句