How to avoid making long constructors [duplicate] - java

This question already has answers here:
Elegant alternatives for huge amount of arguments in class constructor [closed]
(4 answers)
Closed 7 years ago.
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?

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!

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.

As Joshua Bloch stated it in Item 2 of Effective Java 2nd Edition, you should consider using a builder pattern, as it is a best practice.
Here is what you code could look like using it :
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 do something as follow :
DataResponse response = new DataResponse.Builder().reponse(anyResponse).isLink(isLink).build();

Related

How to create a class to get the json response of a service which returns in an structure like the following?

The webservice return the following JSON string:
{"errorCode":0,"error":"","status":"OK","data":{"id":"1234A"}}
So to get a class that receives the response in a function like this that performs a post in Retrofit:
Call<UploadImageData> postData(#Header("Cookie") String sessionId, #Body UploadImageModal image);
I'd need to make a class like this;
public class UploadImageData {
private int errorCode;
private String error;
private String status;
}
But I'm lost in how I would have to declare the part that would take "data":{"id":"1234A"}, so it gets the data from there correctly.
How could I do this?
Since data is a nested object within the surrounding json object, you can include it as another class in your UploadImageData class.
public class UploadImageData {
private int errorCode;
private String error;
private String status;
private MyDataClass data;
}
public class MyDataClass {
private String id;
}
DonĀ“t forget setter methods oder make fields public.

How to use builder pattern with all parameters as mandatory? [duplicate]

This question already has answers here:
How to avoid making long constructors [duplicate]
(3 answers)
Elegant alternatives for huge amount of arguments in class constructor [closed]
(4 answers)
Closed 7 years ago.
I have a builder pattern in which most likely all my parameters are going to be mandatory so I have created a long constructor as shown below in the code.
public final class ResponseHolder {
// all below six are related to response information
private final String response;
private final boolean isLinking;
private final TypeHold typeOfId;
private final long userTimeInMs;
private final long userLmdInDays;
private final String maskInfo;
// below two are related to error handling
private final ErrorCode error;
private final StatusCode status;
private ResponseHolder(Builder builder) {
this.response = builder.response;
this.isLinking = builder.isLinking;
this.typeOfId = builder.typeOfId;
this.userTimeInMs = builder.userTimeInMs;
this.userLmdInDays = builder.userLmdInDays;
this.maskInfo = builder.maskInfo;
this.error = builder.error;
this.status = builder.status;
}
public static class Builder {
protected final String response;
protected final TypeHold typeOfId;
protected final String maskInfo;
protected final ErrorCode error;
protected final StatusCode status;
protected final boolean isLinking;
protected final long userTimeInMs;
protected final long userLmdInDays;
public Builder(String response, TypeHold typeOfId, String maskInfo, ErrorCode error,
StatusCode status, boolean isLinking, long userTimeInMs, long userLmdInDays) {
this.response = response;
this.typeOfId = typeOfId;
this.maskInfo = maskInfo;
this.error = error;
this.status = status;
this.isLinking = isLinking;
this.userTimeInMs = userTimeInMs;
this.userLmdInDays = userLmdInDays
}
public ResponseHolder build() {
return new ResponseHolder(this);
}
}
// getters here
}
Now I am confuse when all the parameters are mandatory, then how it can be useful? Is there any better way of representing my above Builder pattern? May be logically grouping the parameters being passed in to their own classes to reduce the number of parameters being passed to the builder constructor?
While having separate objects simplifies things quite a bit, it also makes things a little difficult to follow if one is not familiar with the code. One thing I can do is moving all parameters into their own addParam(param) methods and then performing validation on required parameters in the build() method at runtime?
What is best practice I should follow here and is there any better approach that I can use here?
The Builder pattern shines when there are many different valid parameter permutations that allow you to create an object. Without the Builder pattern, you would be forced to create many ugly and confusing constructors to handle all the possible valid parameter combinations.
But in your case, there is only one valid set of parameters that allows you to create your object. This is exactly what a constructor is for. Using the Builder pattern here is not only overkill, it simply is not appropriate.
Just use a normal constructor for your ResponseHolder class.
The purpose of the builder pattern is to have a no-arg constructor, many well-named setter methods, and a final completion method, which validates that combination of values given are valid, before constructing the target object.
In your case, since all values are required, the main purpose of the builder pattern is to provide a form of named-parameter support.
Also, your target object should have many-arg constructor, rather than taking builder object as argument)
So, your builder should be (assuming no null values allowed):
public static class Builder {
private String response;
private TypeHold typeOfId;
private String maskInfo;
private ErrorCode error;
private StatusCode status;
private Boolean isLinking;
private Long userTimeInMs;
private Long userLmdInDays;
public Builder setResponse(String response) {
this.response = response;
return this;
}
public Builder setTypeOfId(TypeHold typeOfId) {
this.typeOfId = typeOfId;
return this;
}
public Builder setMaskInfo(String maskInfo) {
this.maskInfo = maskInfo;
return this;
}
public Builder setError(ErrorCode error) {
this.error = error;
return this;
}
public Builder setStatus(StatusCode status) {
this.status = status;
return this;
}
public Builder setIsLinking(boolean isLinking) {
this.isLinking = isLinking;
return this;
}
public Builder setUserTimeInMs(long userTimeInMs) {
this.userTimeInMs = userTimeInMs;
return this;
}
public Builder setUserLmdInDays(long userLmdInDays) {
this.userLmdInDays = userLmdInDays;
return this;
}
public ResponseHolder build() {
if (this.response == null ||
this.typeOfId == null ||
this.maskInfo == null ||
this.error == null ||
this.status == null ||
this.isLinking == null ||
this.userTimeInMs == null ||
this.userLmdInDays == null) {
throw new IllegalStateException("Not all required values given");
}
return new ResponseHolder(this.response,
this.typeOfId,
this.maskInfo,
this.error,
this.status,
this.isLinking,
this.userTimeInMs,
this.userLmdInDays);
}
}
You can now use it like this:
ResponseHolder holder = new ResponseHolder.Builder()
.setResponse(response)
.setTypeOfId(typeOfId)
.setMaskInfo(maskInfo)
.setError(error)
.setStatus(status)
.setIsLinking(isLinking)
.setUserTimeInMs(userTimeInMs)
.setUserLmdInDays(userLmdInDays)
.build();

Copying object of class A to object of Class B, where A and B have very similar composition

I am trying to do the following redundant code - copying a Class FeedDBTableRow's object into a Feed object - where they mostly have overlapping set of variables, and I am trying to copy those common set of variables. Is there a design pattern or an annotation processor that helps me reduce these (potentially bug-prone) lines of code?
The reason for doing this basically I want to use Retrofit with GSon and Realm (and Realm due to its own construction, needs the Pojo to extend from RealmObject class, while doing this creates a GSON error - it is documented at several places)
public static Feed getFeedFromDBFeedRow(FeedDBTableRow f){
Feed x = new Feed();
x.setId(f.getId());
x.setText(f.getText());
x.setTime_created(f.getTime_created());
x.setTime_modified(f.getTime_modified());
x.setComments_count(f.getComments_count());
x.setLikes_count(f.getLikes_count());
x.setFeed_type(f.getFeed_type());
x.setObj_id(f.getObj_id());
x.setImage(f.getImage());
x.setUser_name(f.getUser_name());
x.setUser_earthmile_points(f.getUser_earthmile_points());
x.setLiked(f.isLiked());
x.setCommented(f.isCommented());
x.set_private(f.isIs_private());
x.setUrl(f.getUrl());
x.setFeed_creator_id(f.getFeed_creator_id());
return x;
}
My Feed class is:
public class Feed {
int id;
String text;
Date time_created;
Date time_modified;
int comments_count;
int likes_count;
String feed_type;
int obj_id;
String image;
String user_name;
String user_earthmile_points;
boolean liked;
boolean commented;
boolean is_private;
String url;
int feed_creator_id;
public Feed() {} // required for being Parcelable
}
And the FeedDBTableRow class is :
public class FeedDBTableRow extends RealmObject{ // having this necessity to extend RealmObject is the source of all problem, but I have to do this, hence two classes with similar composition
private int id;
private String text;
private Date time_created;
private Date time_modified;
private int comments_count;
private int likes_count;
private String feed_type;
private int obj_id;
private String image;
private String user_name;
private String user_earthmile_points;
private boolean liked;
private boolean commented;
private boolean is_private;
private String url;
private int feed_creator_id;
}
Take a look at Apache BeanUtils: http://commons.apache.org/proper/commons-beanutils/javadocs/v1.9.2/apidocs/index.html
In particular, BeanUtils.copyProperties() might be something you find useful.

Null Object Pattern - public static final

I saw sometime in the last month an implementation of Null Object pattern as what seemed like a Singleton field on a type. I can't really remember the approach though. I'm working on patterns and conscious of implementing them out of place.
From my mind I think it would be as follows but can I get a review on that?
public final class SearchCriteriaAnomalyFilter {
public static final SearchCriteriaAnomalyFilter NULL_INSTANCE;
private final T2AnomalyStatus status;
private final T2AnomalyType type;
private final boolean limitMaxOneAnomaly;
public SearchCriteriaAnomalyFilter(T2AnomalyStatus status, T2AnomalyType type,
boolean limitMaxOneAnomaly){
this.status = status;
this.type = type;
this.limitMaxOneAnomaly = Boolean.valueOf(limitMaxOneAnomaly);
}
private SearchCriteriaAnomalyFilter(){}
public static SearchCriteriaAnomalyFilter instanceOfNullObject(){
if (NULL_INSTANCE == null) {
NULL_INSTANCE = new SearchCriteriaAnomalyFilter();
}
return NULL_INSTANCE;
}
...
}
public static final SearchCriteriaAnomalyFilter NULL_INSTANCE = new SearchCriteriaAnomalyFilter();
public static SearchCriteriaAnomalyFilter instanceOfNullObject(){
return NULL_INSTANCE;
}
The rest of your code seemed fine.
The reason to use the above construct is that there is no need for a lazy initialization: the null-object won't change, nor does it need any special construction (as you properly implemented with the private constructor).

Using #SuppressWarnings("unused") annotation on declaration section

I have a basic question relating to the #SuppressWarnings("unused") annotation. Basically, I would like to suppress unused warnings on a block of code in my declarations section of my class. I would prefer not to suppress unused warnings on the entire class.
Currently, I am doing this:
public class MyClass {
//Constants
private final String ACCEPT = "Yes";
#SuppressWarnings("unused")
private final String DENY = "No"; //Not currently used
private final String TENTATIVE = "Maybe";
#SuppressWarnings("unused")
private final String POSTPONE = "Later"; //Not currently used
//Variables
private int counter;
....
I find the above code to be a bit messy with the annotations thrown in randomly like that. What I would like to do is something like:
//Constants
#SuppressWarnings("unused")
{
private final String ACCEPT = "Yes";
private final String DENY = "No"; //Not currently used
private final String TENTATIVE = "Maybe";
private final String POSTPONE = "Later"; //Not currently used
}
//Variables
private int counter;
....
This is, of course, illegal in Java as a block cannot be simply made like this. Its not a huge deal or anything, but I am curious if I am missing an obvious and elegant solution.
If you reeeeealy want to keep all those unused constants, a quick and dirty trick would be;
public class MyClass {
//Variables
private int counter;
#SuppressWarnings("unused")
private static final class UnusedConstants{
private final String ACCEPT = "Yes";
private final String DENY = "No";
private final String TENTATIVE = "Maybe";
private final String POSTPONE = "Later";
}
}
And i would make them static too, but your call.
EDIT:
Or, what i think is much nicer:
public class MyClass {
private enum Answer {
ACCEPT ("Yes"),
DENY ("No"),
TENTATIVE("Maybe"),
POSTPONE("Later");
private final String answer;
private Answer(String answer) {
this.answer = answer;
}
public String toString() {
return answer;
}
}
}
This way you don't get the unused warning as long as you use at least one of the values.

Categories

Resources