Java 如何避免长构造函数
我有一个客户端库,在该库中,我对我的rest服务进行http远程调用,然后我将Java 如何避免长构造函数,java,constructor,enums,Java,Constructor,Enums,我有一个客户端库,在该库中,我对我的rest服务进行http远程调用,然后我将列表返回给调用我们库的客户,该客户使用我从我的rest服务获得的响应以及任何错误(如果有任何环绕数据响应对象) public class DataResponse { private final String response; private final boolean isLink; private final TypeOfId idType; private final long
列表
返回给调用我们库的客户,该客户使用我从我的rest服务获得的响应以及任何错误(如果有任何环绕数据响应
对象)
public class DataResponse {
private final String response;
private final boolean isLink;
private final TypeOfId idType;
private final long ctime;
private final long lmd;
private final String maskInfo;
// below are for error stuff
private final ErrorCode error;
private final StatusCode status;
// constructors and getters here
}
这是我的ErrorCode
enum类:
public enum ErrorCode {
// enum values
private final int code;
private final String status;
private final String description;
// constructors and getters
}
public enum StatusCode {
SUCCESS, FAILURE;
}
这是我的StatusCode
enum类:
public enum ErrorCode {
// enum values
private final int code;
private final String status;
private final String description;
// constructors and getters
}
public enum StatusCode {
SUCCESS, FAILURE;
}
正如您在我的DataResponse
类中所看到的,我有很多字段,因此我有一个很长的构造函数,每次我创建DataResponse
对象时,我都会对新的DataResponse(……)
进行大量排序。将来我可能会有更多的字段,但现在我只有这些字段
有没有比java更好的方法来制作<代码>数据响应> /代码>对象,然后从我的库中返回代码<清单>代码>?< /p> < p>正如Joshua Bloch在有效Java第二版的第2条中所陈述的,你应该考虑使用构造器模式,因为这是一个最佳实践。 下面是您使用它编写代码的样子:
public class DataResponse {
private final String response;
private final boolean isLink;
private final TypeOfId idType;
private final long ctime;
private final long lmd;
private final String maskInfo;
// below are for error stuff
private final ErrorCode error;
private final StatusCode status;
// constructors and getters here
public static class Builder {
private final String response;
private final boolean isLink;
private final TypeOfId idType;
private final long ctime;
private final long lmd;
private final String maskInfo;
// below are for error stuff
private final ErrorCode error;
private final StatusCode status;
public Builder reponse(final String response) {
this.response = response;
return this;
}
public Builder isLing(final boolean isLink) {
this.isLink = isLink;
return this;
}
public DataResponse builder() {
return new DataResponse(this);
}
...
}
private DataResponse(final Builder builder) {
this.response = builder.response;
this.isLink = builder.isLink;
}
}
然后做如下事情:
DataResponse response = new DataResponse.Builder().reponse(anyResponse).isLink(isLink).build();
也许您可以识别较小的逻辑字段组,并将它们移动到自己类的对象中。然后可以将所有这些对象组合到
DataResponse
对象中 不要立即使用。它不适用于具有大量必填字段的类型。它适用于具有大量可选字段的类型
构建器所需的属性通过构造函数指定。您不会被迫使用方法定义值,这使得这些值是可选的
这使得您的对象可能只被部分构造。使用构建器进行此操作将是对设计的滥用
话虽如此,你还是应该选择你喜欢的类型。我不确定什么是
lmd
或ctime
,也不确定DataResponse
应该代表什么,所以我无法告诉您应该以何种方式分解。但我可以告诉你,是什么决定了这一切
isLink
、maskInfo
和idType
可能会分解为一个DataResponseDetails
对象:
class DataResponseDetails {
private boolean isLink;
private String maskInfo;
private TypeOfId idType;
public DataResponseDetails(boolean isLink, String maskInfo, TypeOfId idType) {
//...
}
}
现在您的DataResponse
可以由DataResponseDetails
组成:
class DataResponse {
private DataResponseDetails details;
private String response;
//...
public DataResponse(DataResponseDetails details, String response, ...) {
//...
}
}
你觉得你的构造器需要太多的静物吗?分解更多 您可以使用生成器模式。我还不需要依赖生成器。你有很多领域?听起来像是分解的工作。退房如果您仍然觉得之后向构造函数传递了太多数据,那么可以使用构建器模式。虽然适当的分解通常会起作用。我发现构造器对于可选参数很有用(避免压缩提供默认值的构造器,而不是避免大量参数)@AshishAni我认为你没有正确解释这一章。我也读过有效的Java,它使用营养信息作为构建器的示例-一些营养值是可选的,因此构建器模式是一个很好的设计scenario@YoungHobbit读我的答案。它详细说明了为什么构建器模式不适合“大量的构造函数参数”。我很惊讶这么多人误解了这个模式的目的。我想补充一点,对我来说,使用可选类(来自Guava或Java8的类)作为可选字段,以消除空值,应该被认为是一种最佳实践