如何通过建造者模式强制设置参数的顺序

4

最近,我在面试中被要求实现Builder模式,以便用户在设置参数B之前无法设置参数A。

我建议在构建Builder时将A作为必需参数传递,但他对我的答案不满意。 我还建议在设置B时,如果未设置A,则抛出IllegelStateException,但他再次表示不满意。 有人能否建议如何强制用户在设置B之前先设置A?

class Example{
private int A;
private int B;

public static class Builder{
}

}


3
您需要创建单独的生成器类,第一个用于设置A,然后返回值是第二个生成器实例,用于设置B。 - Andy Turner
@AndyTurner,我有另一个字段C,如果我先设置了字段A的值,那么我将无法设置字段C的值,因为它会返回字段B的构建器。或者我能够设置吗? - Ankur
2个回答

2
用普通的Java来实现,你需要创建单独的Builder类,第一个用于设置A,返回值是第二个Builder的实例,用于设置B。
这种方法的局限性之一是非常冗长,并且不适用于有很多可选参数的情况。
或者,我通过编写编译器插件来实现此功能(我使用了Error Prone,因为它最容易与Google的构建系统配合使用,但也可以使用其他工具),该插件检查方法调用顺序。

0

主要思路是在setAsetB方法中使用不同的返回类型,但这些类型必须是构建器类型的相同类型或子类型。

public class ExampleBuilderImpl implements  FullExampleBuilder {
private int a;
private int b;



public Example createExample() {
    return new Example(a, b);
}

@Override
public PartExampleBuilder setB(int b) {
    this.b = b;
    return this;
}

@Override
public FullExampleBuilder setA(int a) {
    this.a = a;
    return this;
}


public static void main(String[] args) {


    ExampleBuilderImpl builder = new ExampleBuilderImpl();

    // compiler error
   //       builder.setB(1).setA();

    builder.setA(1).setB(2);

}

}

public interface FullExampleBuilder extends PartExampleBuilder {
    FullExampleBuilder setA(int a);

}



public interface PartExampleBuilder {
    PartExampleBuilder setB(int b);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接