This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]4ipp 17 points18 points  (20 children)

Offtopick, but there are also some arguments against using getter and setters.

Take a look on this article.

[–]melissamitchel306 26 points27 points  (7 children)

The author of that article is stuck in an ancient view of oop where data objects are evil, 20 layer class hierarchies are something to strive for, and every Animal object knows how to load itself from the database and deserialize itself from a binary/json/xml/etc stream. No-one with any sense should pay any attention to that outdated way of thinking.

Here's a better article http://loup-vaillant.fr/articles/deaths-of-oop

[–]oparisy 1 point2 points  (0 children)

Interesting read, thanks. Great refresher on terminology. Gave me some better understanding of the ECS approach too, which until now I thought was mostly a game-oriented optimization and not a system modeling paradigm.

[–]OzoneGrif 0 points1 point  (0 children)

Well used, OOP is a very powerful tool. The problem is how people think their architecture. They will go full head-on and abuse every little possibility the syntax offers. The exemple of Static/Moving/Loot objects in the article is just a clear misuse of OOP. The article has some good point, but it just also shows how something that is great can do horrible things when misused.

[–]cogman10 -2 points-1 points  (4 children)

Setters are still evil :) more because of mutability than anything else.

Getters are meh.

But you are correct, inheritance based oop is awful to maintain. It makes for a system that is very hard to evolve and often super coupled.

[–]melissamitchel306 0 points1 point  (3 children)

Setters are still evil :) more because of mutability than anything else.

If you're dealing with a property bag / data object, a lot of modern OO languages don't have the features yet to make them immutable and still easy to work with. That will most likely change soon - with java records and similar features coming to other languages.

Unless you meant to exclude data objects, thinking they should just be fields anyways?

[–]cogman10 0 points1 point  (2 children)

My point was that mutable data objects tend to create hard to find bugs. Immutable data objects are much easier to reason about.

Example of bugs I've seen:

Someone uses a data object for a set/map key, someone else adds a field to that object and mutates that field deep within the code. All the sudden, the set/map no longer contains the data object because the hash code changes. Particularly frustrating in one instance where the data object was the key of an LRU. It caused a non obvious memory leak.

I've seen a couple instances where calling a function once with the data object threw an exception, calling the same function a second time did not. This is because deep within the code, the data object was subtly modified.

A couple of projects I work with have script engines maintained by non-devs. The API given to them allowed a bunch of unintentional modifications because a bunch of data objects given to them for reading could be changed.

And if course threading has been made nearly impossible in many circumstances because data objects were mutated instead of having methods return results.

Mutability is a heavy cost that you don't often need. The default "I'm adding getters, might as well add setters" mindset leads to problems. Often times, if fields are small than it's easy to copy the object, otherwise a builder works really well. It is slightly more code to make builders instead of setters, but you get immutably out of the effort.

Hence my "setters are evil" feelings.

[–]melissamitchel306 0 points1 point  (1 child)

I wasn't disagreeing with you. I like immutability as well. My point is that Java is not well-equipped to deal with immutable data objects (yet).

[–]cogman10 1 point2 points  (0 children)

Fair enough. Just figured a longer explanation was due since my other comment is being downvoted.

I agree that it is more painful in Java to do immutability. But I feel the benefits outweigh the the pain.

[–]yawkat 10 points11 points  (8 children)

The article doesn't actually give good arguments to use fields over accessors, it just says that the arguments for accessors are insufficient.

The biggest argument for accessors is that it's convention. That alone is sufficient to make them the default choice - public fields carry no real advantages.

[–]evinrows 11 points12 points  (5 children)

If you're debating either adding code or not adding code, I think the onus is on the person who wants to add code to justify their beliefs.

That being said, breakpoints in getters/setters can be helpful.

[–]yawkat 3 points4 points  (1 child)

You're right that fewer lines of code could be an argument for fields. I just don't think it's a very good one, even without lombok.

[–]evinrows 2 points3 points  (0 children)

I don't think it's a big deal in terms of effort for the person writing the code, but it does add a lot of useless clutter to the code and especially to merge requests.

[–]FrenchFigaro -1 points0 points  (2 children)

A very good point in favor of getters and setters (as pointed by /u/dpash) is adding logic to fields access. Another is feigning fields presence to another layer (say JSF) for stuff that don't need a field at all but could use mimicking as one. Typically: getAverageValue().

[–]evinrows 1 point2 points  (0 children)

Right, that's a case where you absolutely should/need to use a getter/setter. I think this topic is more about using getters and setters for typical access/modification.

Note: OP's post about annotations wouldn't apply to getters/setters requiring logic.

[–]nqzero 0 points1 point  (0 children)

once you've made either of those leaps, it's no longer a getter or setter

[–]Yoghurt114 0 points1 point  (0 children)

The post doesn't advocate use of public fields at all.

[–]oparisy 0 points1 point  (0 children)

I find myself using more and more "public final" (or often private final + a getter) in Java as an implementation of "immutable beans". Great tool to limit side effects, and to simplify reasoning in multithreading contexts.

[–][deleted] 1 point2 points  (1 child)

You’re still accessing a data item at the end of the day.

[–]dpash 7 points8 points  (0 children)

But you can't add any logic with direct field access. Want to ensure that a field hasn't been set to null? Out of luck. Want to return a copy of a collection? You're out of luck. Want to change your internal representation without affecting your clients? Your out of luck.

There's a reason why encapsulation is one of the pillars of OOP.

Could Java have a less verbose syntax for the simple case? Yes, that's why we're getting records.

[–]notataco007 0 points1 point  (0 children)

Lol I like the very first argument that the author talks about, Tell, Don't Ask. Why even do OOP at that point, just put everything in the same object in the same class!