java - 在 Java 中使用扭曲的子类化构建器模式

标签 java design-patterns

我想为一个抽象类创建一个抽象生成器(虽然它不需要是抽象的)并且抽象类的每个子类都可以有自己的子类生成器。我还希望每个字段/属性都被强制填写。所以我使用了 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/

相关文章:

java - QuickfixJ 必填字段缺失,即使它存在

java - Java 中大括号的正则表达式 Number 大括号 ({n})

java - play japid 为什么不能使用可变参数

c++ - 在 C++ 中应用抽象工厂设计模式

java - instanceof 与 isAnX()

java - 在 Tomcat 上运行的基于 Spring-Boot 的 WAR 上,在哪里以及如何启用 CORS?

java - (Java初学者)为什么我的数组为空?

java - DAO 模式和模型对象

多线程情况下的Java设计模式: Factory vs Singleton?

c# - 如何避免私有(private)属性空检查做延迟加载?