如何通过构建器模式强制设置参数的顺序
How to enforce order of setting parameters through Builder Pattern
最近,我在面试中被要求以这样一种方式实现构建器模式,即除非设置了参数 A,否则用户无法设置参数 B。
我建议在构建Builder时将A作为必需参数传递,但他对我的回答不满意。
我还建议如果在设置 B 时未设置 A 则抛出 IllegelStateException 但他还是不满意。
谁能建议我们如何强制用户在设置 B 之前先设置 A?
class Example{
private int A;
private int B;
public static class Builder{
}
}
要以简单的方式做到这一点 Java,您需要创建单独的 Builder 类,第一个用于设置 A,因此返回值是第二个 Builder 的实例,用于设置 B.
这种方法的局限性之一是它非常冗长,并且不能很好地扩展到具有大量可选参数。
或者,我通过编写编译器插件来完成此操作(我使用 Error Prone,因为使用 Google 的构建系统最容易做到这一点,但没有理由其他工具不能'被使用)检查方法调用顺序。
主要思想是在 setA
setB
方法中使用不同的 return 类型,但这些类型必须是构建器类型的相同类型或子类型。
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);
}
最近,我在面试中被要求以这样一种方式实现构建器模式,即除非设置了参数 A,否则用户无法设置参数 B。
我建议在构建Builder时将A作为必需参数传递,但他对我的回答不满意。 我还建议如果在设置 B 时未设置 A 则抛出 IllegelStateException 但他还是不满意。 谁能建议我们如何强制用户在设置 B 之前先设置 A?
class Example{
private int A;
private int B;
public static class Builder{
}
}
要以简单的方式做到这一点 Java,您需要创建单独的 Builder 类,第一个用于设置 A,因此返回值是第二个 Builder 的实例,用于设置 B.
这种方法的局限性之一是它非常冗长,并且不能很好地扩展到具有大量可选参数。
或者,我通过编写编译器插件来完成此操作(我使用 Error Prone,因为使用 Google 的构建系统最容易做到这一点,但没有理由其他工具不能'被使用)检查方法调用顺序。
主要思想是在 setA
setB
方法中使用不同的 return 类型,但这些类型必须是构建器类型的相同类型或子类型。
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);
}