子类化构建器模式与Java中的扭曲 [英] Subclassing builder pattern with a twist in Java

查看:139
本文介绍了子类化构建器模式与Java中的扭曲的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为抽象类创建一个抽象的构建器(虽然它不需要是抽象的),抽象类的每个子类都可以有自己的子类Builder。我还希望每个字段/属性都填写AKA强制。所以我使用带有扭曲的Builder Pattern( https ://blog.jayway.com/2012/02/07/builder-pattern-with-a-twist/ )。

I would like to create an abstract Builder for an abstract class (although it does not need to be abstract) and every subclass of the abstract class could have its own subclass Builder. I also want every field/attribute to be filled AKA mandatory. So I use the Builder Patter With a Twist (https://blog.jayway.com/2012/02/07/builder-pattern-with-a-twist/).

我遇到了问题在我之前问过的这个问题中解决了这个问题:通用父对象不能作为没有强制转换的子项返回
但是现在我无法生成多个具体/子类构建器。

I encountered a problem which was solved in this question I asked earlier: Generic parent object cannot be returned as child without cast But now I am unable to make multiple concrete/subclass Builders.

最后我想实例化像这样的对象:

In the end I would like to instantiate objects something like this:

ConcreteBuilderA.getBuilder().setValue(Object value).setConcreteValue(int num).build()

其中setValue()属于AbstractBuilder及其他到了concreteBuilder。

Where setValue() belongs to the AbstractBuilder and the others to the concreteBuilder.

我最好的镜头是(大大简化和抽象) :

My best shot was (heavily simplified and abstracted):

/**
* @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);
}

如果标记,这会在切换到子类构建方法时停止链。
我已经为此制作了一些变种,我无法让它发挥作用。

As marked, this stops the chain when 'switching' to the subclass build methods. I have made some variants to this and I cannot get it to work.

所以我真的很想知道这是否可行。如果是的话,我想看看如何。如果不是,我想知道一些符合我要求的技术。

So I am really wondering if this is even possible. If it is, I would like to see how. If it isn't I would like know some technique that does meet my requirements.

提前致谢!

推荐答案

我在Federico Peralta Schaffner的帮助下找到了答案。
很可能我在实际项目中使构建器变得复杂。
所以这里是Builder-with-a-twist +继承的代码:

I discovered the answer with the with the help of Federico Peralta Schaffner. It is likely that I made the builder in my real project to complicated. So here is the code for a Builder-with-a-twist + inheritance:

/**
 *
 * @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中的扭曲的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆