Entity objects getters and setters for data properties
-
03-07-2019 - |
Question
I recently started working in Java and was introduced to the wild and crazy world of getters and setters for everything. I hated it at first, but quickly got used to it. Too used to it.
I have been spending a lot of time lately thinking more about class design. One of the things I am trying to do is avoid the trap of doing getters and setters for everything. However, much of the work I do is with entities that are mainly data containers and I am not certain that getters and setters are actually inappropriate in these cases.
Here is a simple example using public properties.
class Space {
public String name;
public String description;
Space(final String name, final String description) {
this.name = name;
this.description = description;
}
}
Here is a simple example using private properties and using getters and setters.
class Space {
private String name;
private String description;
Space(final String name, final String description) {
this.name = name;
this.description = description;
}
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(final String description) {
this.description = description;
}
}
In these examples, both the name
and the description
fields should be able to be changed.
I feel like the getter/setter example is more clear and hides the implementation details of what name
and description
are. It would also allow for validation on set later if needed.
I have read several discussions about getters and setters being evil and/or an anti-pattern, but it really feels like those might not apply to this situation.
Maybe there are some options I have not yet considered. I'm open for suggestions!
Solution
To put it simple:
- You need getters for all fields that must be read from the outside.
- You need setters for all fields that must be written from the outside.
This can be 100%, but most of the time it is less.
OTHER TIPS
The first version (public properties) is not a good idea. The second is better. As Josh Bloch would say, "favor immutability":
public class Space {
private final String name;
private final String description;
public Space(final String name, final String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
}
That being said, getters and setters tend to be overused.
You have heard the often oversimplified "get/setters are evil". Nobody (I hope) really means that there's anything wrong with it for data objects. I think the real idea is:
"Getters/Setters are evil, except for plain data storage objects" which itself is just an evangelism of "tell don't ask".
Ideally if a class has getters and setters, that's all it should have.
That's the argument anyway. I'm not sure I agree with it.
While the accessor pattern helps hide the implementation details of a class (e.g. using a hashtable to store attributes to save memory on sparsely used classes), it can be very verbose to implement (your example has 12 lines more with accessors). That's why C# has a special property syntax, which allows to concisely specify default accessors:
class Space {
public String Name { get; set; }
public String Description { get; set; }
Space(final String name, final String description) {
this.Name = name;
this.Description = description;
}
}
Alternative forms may add access specifiers and/or code:
private String _name;
public String Name {
get { if (_name == null) FetchName(); return _name; }
private set { _name = value; }
}