我想为一个抽象类创建一个抽象生成器(虽然它不需要是抽象的)并且抽象类的每个子类都可以有自己的子类生成器。我还希望每个字段/属性都被强制填写。所以我使用了 Builder Patter With a Twist ( https://blog.jayway.com/2012/02/07/builder-pattern-with-a-twist/ )。
我遇到了一个问题,我之前问的这个问题已经解决了:Generic parent object cannot be returned as child without cast 但是现在我无法创建多个具体/子类生成器。
最后我想像这样实例化对象:
ConcreteBuilderA.getBuilder().setValue(Object value).setConcreteValue(int num).build()
其中 setValue() 属于 AbstractBuilder,其他属于 concreteBuilder。
我最好的镜头是(高度简化和抽象):
/**
* @param<B> the type of builded object it should return.
* @param<S> the type of the builder subclass.
* @param<L> the type of the linking interface.
*/
public abstract class AbstractBuilder<B extends AbstractClass, S extends AbstractBuilder, L> implements ValueSetter<L>
{
protected B buildable;
@Override
public L setValue(Object value)
{
//set the value
return this;//<-- returns Object, blocking the use of the ConcreteBuilder methods
}
public abstract B build();
}
|
public class ConcreteBuilder extends AbstractBuilder<ConcreteProduct, ConcreteBuilder, ConcreteValueSetter> implements ConcreteValueSetter
{
@Override
public ConcreteBuilder setConcreteValue(int num)
{
//set value
return this;
}
@Override
public ConcreteProduct build();
{
return buildable;
}
}
|
public interface ValueSetter<L>
{
public L setValue(Object value);
}
|
public interface ConcreteValueSetter
{
public ConcreteBuilder setConcreteValue(int num);
}
如标记的那样,这会在“切换”到子类构建方法时停止链。 我为此做了一些变体,但我无法让它工作。
所以我真的很想知道这是否可能。如果是的话,我想看看如何。如果不是,我想知道一些确实满足我要求的技术。
提前致谢!
最佳答案
在 Federico Peralta Schaffner 的帮助下,我找到了答案。 很可能我在我的真实项目中使构建器变得复杂。 所以这里是 Builder-with-a-twist + 继承的代码:
/**
*
* @param <P> the type of the product.
* @param <L> the linking interface.
*/
public class AbstractBuilder<P extends AbstractClass, L> implements ValueSetterOne<L>, ValueSetterTwo<L>{
protected P toBeBuild;
@Override
public L setValueTwo(int value) {
//set value
return (L) this;
}
@Override
public ValueSetterTwo<L> setValueOne(int value){
//set value
return this;
}
|
public class ConcreteBuilder extends AbstractBuilder<ConcreteClass, NameSetter> implements NameSetter, Optional{
public static ValueSetter<NameSetter> getBuilder()
{
AbstractBuilder<ConcreteClass, NameSetter> builder = new ConcreteBuilder();
builder.toBeBuild = new ConcreteClass();
return builder;
}
@Override
public Optional buildName(String name) {
this.toBeBuild.setCharacterName(name);
return this;
}
@Override
public ConcreteClass build() {
return this.toBeBuild;
}
@Override
public Optional addExtraObject(Object extra) {
System.out.println("test");
return this;
}
}
|
public interface ValueSetterOne<L> {
public ValueSetterTwo<L> setValueOne(int value);
}
|
public interface ValueSetterTwo<L> {
public L setValue(int value);
}
|
public interface NameSetter {
public Optional buildName(String name);
}
|
public interface Optional {
public ConcreteClass build();
public Optional addExtraObject(Object extra);
}
然后进行测试:
ConcreteBuilder.getBuilder().setValueOne(0).setValueTwo(1).buildName("tricky").addExtraObject(args).build();
关于java - 在 Java 中使用扭曲的子类化构建器模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44527022/