如何避免制作长构造函数

我有一个客户端库,我正在对我的rest服务进行http远程调用,然后我将List返回给正在调用我们的库的客户,我从REST服务获得的响应以及任何错误,如果有任何包裹DataResponse对象。

 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枚举类:

 public enum ErrorCode { // enum values private final int code; private final String status; private final String description; // constructors and getters } 

这是我的StatusCode枚举类:

 public enum StatusCode { SUCCESS, FAILURE; } 

正如你在我的DataResponse类中看到的那样,我有很多字段,所以我有一个很长的构造函数,每当我创建一个DataResponse对象时,我都有一个new DataResponse(.......) 。 将来我可能会有更多的字段但是现在我只有这些字段。

有没有更好的方法可以用来创建一个DataResponse对象,然后从我的库中返回List

不要立即使用构建器模式 。 它不适用于具有大量必填字段的类型。 它适用于包含大量可选字段的类型。

通过构造函数指定构建器的必需属性。 您不必使用方法定义值,这使得这些值是可选的。

这样,您的对象只能部分构建 。 使用构建器可能会滥用设计。


话虽如此,你应该分解你的类型。 我不确定lmdctime是什么,或者确实是DataResponse应该代表什么,所以我不能告诉你应该以哪种方式分解。 但我可以告诉你凝聚力决定了这一点。

isLinkmaskInfoidType可能会被分解为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, ...) { //... } } 

感觉你的构造函数需要太多了吗? 分解更多!

也许你可以识别较小的逻辑字段组,将它们移动到自己类的对象中。 然后,您可以在DataResponse对象中组合所有这些对象。

正如Joshua Bloch在Effective Java 2nd Edition的第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();