This question already has answers here:
Elegant alternatives for huge amount of arguments in class constructor [closed]

(4个答案)


5年前关闭。




我有一个客户端库,在其中我要对我的REST服务进行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对象时,我与new DataResponse(.......)都有很大的区别。将来我可能会有更多字段,但目前只有这些字段。

有什么更好的方法可以用来制作DataResponse对象,然后从库中返回List<DataResponse>吗?

最佳答案

不要立即使用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, ...) {
        //...
    }
}

觉得您的构造函数仍然需要太多空间?分解更多!

07-24 20:21