DEV Community

Discussion on: Avoid getters and setters whenever possible

Collapse
 
elcotu profile image
Daniel Coturel

Hi Scott, thanks for your answer.

I intended to leave the option 2 as the "more adequate" because the other two are very, very smelly.

Option 2 is more addequate but I wasn't thinking in a case like the one you describe. That case is not a change of behaviour in the getter, but a change in the behaviour of the class. I was thinking in some other cases:

1) Let's say you start with a setter that only does this:

public void setLastName(String ln) {
this.lastName = ln;
}

But in the future, you want to keep track of the modified fields after last read of the database, so in the next update you can only set those fields.

So you add an array of "touched" fields and say, "ok, so when every field is touched by a setter I will add it to the array". Like this:

public void setLastName(String ln) {
this.setTouchedField("lastName");
this.lastName = ln;
}

If you didn't had the setter in the first place, then it would be a pain in the ass adding this behaviour.

2) Let's say you have an object composed of some other objects. Your constructor creates an instance of every each object. But at some point you realize that you want to initialize some of the objects not on parent constructor, but when it's needed. So you could do something like this:

public CustomObject getInstanceOfCustomObject() {
if (this.instanceOfCustomObject == null) {
this.instanceOfCustomObject = new CustomObject();
}
return(this.instanceOfCustomObject);
}

These are some examples I had in mind when I said that it is at some point good to have those getters and setters already coded, even if they are initially totally dumb implementations.

Saludos,

Thread Thread
 
scottshipp profile image
scottshipp

Thanks for the thoughtful questions Daniel! In both cases, I think its still worth asking if there's not some behavior that can be exposed publicly instead of just exposing data. It is easy (because there's so many programmers doing it) to think in terms of data classes being passed around to behavior classes. This is not object-oriented, though. It's a near-cousin to global variables and procedural code operating on those variables. The paper Jason C. McDonald posted in the comments here is a pretty good discussion of these issues.

Unfortunately, both of the examples you gave are going to be prone to concurrency issues that are more serious than the discussion of whether they use "get" style methods. For the second example, try switching to the Initialization-on-demand holder instead. As far as the fact that the method is named "getInstance()" I would not put this in the same category as the getters/setters described in this article. This is a static factory method.

For your example 1, I feel that using the decorator pattern to track the changes in a separate class might be a better approach since it would be a cleaner separation of responsibilities, and you could dynamically add the change-tracking capability only where its needed. OTOH, you don't want to make a whole separate class if its not needed. If you really need to be able to track changes everywhere, then keep it as you showed (but think about concurrency!).

In that case, it would still have a "getXXXX" method then, and I would not be opposed to that. That's why I wrote:

I'm convinced that getters and setters which just return a class member almost never make sense. But you might write something close to getter/setter functionality as long as you are actually doing something in that method.

Thread Thread
 
elcotu profile image
Daniel Coturel

Hi Scott,
Thanks for your answer. Now I understand a little more about the concept you are communicating.
Saludos,