如何避免制作长构造函数

时间:2015-12-25 18:33:57

标签: java constructor enums

我有一个客户端库,我在其中对我的休息服务进行http远程调用,然后我将List<DataResponse>返回给调用我们的库的客户,我从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对象时我都有一个很大的行{{ 1}}。将来我可能会有更多的领域,但现在我只有这些领域。

有没有更好的方法可以用来制作new DataResponse(.......)对象,然后从我的库中返回DataResponse

3 个答案:

答案 0 :(得分:19)

请勿立即使用builder pattern不适用于包含大量必需字段的类型。它适用于包含大量可选字段的类型。

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

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

话虽如此,你应该decompose你的类型。我不确定lmdctime是什么,或者DataResponse应该代表什么,所以我不能告诉你应该以哪种方式分解。但我可以告诉你cohesion是决定这种情况的原因。

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, ...) {
        //...
    }
}

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

答案 1 :(得分:4)

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

答案 2 :(得分:0)

正如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();