Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid making long constructors [duplicate]

I have a client library in which I am making http remote calls to my rest service and then I am returning List<DataResponse> back to the customer who is calling our library with the response I am getting from my REST service along with any errors if there are any wrapped around DataResponse object.

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

}

Here is my ErrorCode enum class:

public enum ErrorCode {

    // enum values

    private final int code;
    private final String status;
    private final String description;

    // constructors and getters

}

And here is my StatusCode enum class:

public enum StatusCode {
    SUCCESS, FAILURE;
}

As you can see in my DataResponse class I have lot of fields so basis on that I have a very long constructor and everytime when I make a DataResponse object I have a big line with new DataResponse(.......). In future I might have more fields but for now I only have these fields.

Is there any better way I can use to make a DataResponse object and then return back List<DataResponse> from my library?

like image 781
john Avatar asked Dec 25 '15 18:12

john


2 Answers

Do not use the builder pattern right away. It is not for types with tons of required fields. It's for types with tons of optional fields.

Builders' required properties are specified via the constructor. You are not forced to define values using methods, which makes those values optional.

This leaves potential for your object being only partially constructed. Using a builder for this would be abuse of the design.


With that said, you should decompose your type. I'm not sure what lmd or ctime is, or really what a DataResponse is supposed to represent, so I cannot tell you in which way you should decompose. But I can tell you cohesion is what determines such.

isLink, maskInfo and idType could possibly be decomposed into a DataResponseDetails object:

class DataResponseDetails {
    private boolean isLink;
    private String maskInfo;
    private TypeOfId idType;

    public DataResponseDetails(boolean isLink, String maskInfo, TypeOfId idType) {
        //...
    }
}

Now your DataResponse could be composed of DataResponseDetails:

class DataResponse {
    private DataResponseDetails details;
    private String response;
    //...

    public DataResponse(DataResponseDetails details, String response, ...) {
        //...
    }
}

Feel your constructor requires too much still? Decompose more!

like image 107
Vince Avatar answered Sep 18 '22 14:09

Vince


Maybe you can identify smaller logical groups of fields an move them into objects of an own class. Then you can assemble all these objects in your DataResponse objects.

like image 39
J. Su. Avatar answered Sep 22 '22 14:09

J. Su.