作为设计师,您需要确定真正需要哪些字段。没有“可能需要”这样的东西。要使用 Builder Pattern 并强制执行所需的参数,请将字段标记为 final 并通过构造函数注入它们:
public class Request {
// fields
private final String requiredField;
private final String optional1;
private final String optional2;
private Request(RequestBuilder builder) {
requiredField = builder.requiredField;
optional1 = builder.optional1;
optional2 = builder.optional2;
}
// add only getter method to the Request class (builds immutable Request objects)
public static class RequestBuilder {
private final String requiredField;
private String optional1;
private String optional2;
public RequestBuilder(String requiredField) {
this.requiredField = requiredField;
}
public RequestBuilder setOptional1(String optional1) {
this.optional1 = optional1;
return this;
}
public RequestBuilder setOptional2(String optional2) {
this.optional2 = optional2;
return this;
}
public Request build() {
return new Request(this);
}
}
}
构建器强制执行必填和可选字段。构建器正在构建的对象隐藏了构造器,因此它只能通过构建器访问。请求对象中的字段都是最终的,以实现不变性。
要使用,您将执行以下操作:
RequestBuilder builder = new RequestBuilder("required");
Request request = builder.setOptional1("foo").setOptional2("bar").build();
或者您可以在调用构建器构造函数后随时调用build()。
更新:
现在解决您的问题....您可以(可能)修改build() 以检查您有多少“半必需”字段的值并将其与字段总数进行比较。对我来说,这是一个黑客。为此,您有两种选择
- 硬编码字段数并检查总数中有多少仍为空或空。如果未设置的字段数低于某个计数,则抛出一些异常(即
InvalidRequiredFieldCount)。否则,您将返回新实例。为此,您需要在每次调用 setter 方法时增加“计数”。
- 使用反射获取字段列表(数组)并使用此字段并使用此字段计数来计算“必需”字段的最小数量。如果未达到最小值,则抛出异常;如果达到最小值,则返回新的请求实例。
public Request build() throws Exception {
Request request = new Request(this);
int count = 0;
int max = 2;
Field[] allFields = Request.class.getDeclaredFields();
for (Field field : allFields) {
Object o = field.get(request);
if (o != null) {
count++;
}
}
if (count < 2) {
throw new Exception("Minimum number of set fields (2) not reached");
}
return request;
}
这并不漂亮,但它确实有效。如果我运行这个:
RequestBuilder builder = new RequestBuilder("required");
Request request = builder.build();
会导致异常:
Exception in thread "main" java.lang.Exception: Minimum number of set fields (2) not reached
at com.master.oxy.Request$RequestBuilder.build(Request.java:54)
at com.master.oxy.Request.main(Request.java:63)
但是,如果我设置了至少一个可选项,则将返回新实例。