How to avoid creating long constructors

I have a client library in which I make http-remote calls for the recreation service, and then return the List<DataResponse> back to the client, who calls our library with the response that I receive from the REST service, as well as with any error if is there any wrapped around a 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 many fields, so I have a very long constructor, and every time I create a DataResponse object, I have a big line with new DataResponse(.......) . In the future, I may have more fields, but so far I only have these fields.

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

+8
java enums constructor
source share
3 answers

Do not use the linker template . This is not for types with the number of fields required. This is for types with tons of optional fields.

The required properties of builders are set using the constructor. You are not required to define values ​​using methods, which makes these values ​​optional.

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


With that said, you should decompose your type. I'm not sure if lmd or ctime , or indeed what DataResponse should represent, so I cannot tell you how you should decompose. But I can say that cohesion is what defines it.

isLink , maskInfo and idType can 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 can consist of DataResponseDetails :

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

Feeling that your constructor requires too much? Share more!

+14
source share

Maybe you can identify smaller logical groups of fields and move them into objects of your own class. You can then collect all of these objects in your DataResponse objects.

+4
source share

As Joshua Bloch said in Article 2 of Effective Java 2nd Edition, you should consider using a builder pattern as this is best practice.

Here is what you could use for the code:

  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; } } 

and then follow these steps:

 DataResponse response = new DataResponse.Builder().reponse(anyResponse).isLink(isLink).build(); 
0
source share

All Articles