4 ms·
I thought there were two reasons. You can add validation for all setters, and abstract it as an interface later if needed.
by bobmcnamara 2y ago
I thought there were two reasons. You can add validation for all setters, and abstract it as an interface later if needed.
- Pxtl 2y agoAlso lets you maintain your invariants. It's particularly useful for cache invalidation. Like if your object exposes a hash of all its public properties, you can invalidate the cached hash when a prop setter is called with a new value.
- mrkeen 2y agoYou just reminded me of one of my main reasons to avoid getters, which the article didn't mention. Accessing a field will not invoke other code.
- Groxx 2y agoUnless it's synchronized. Then you could deadlock.
- mrkeen 2y agoThis got me curious, so I tried it out. I was unable to put a synchronized onto the field directly: error: modifier synchronized not allowed here public synchronized final Object field; But when I locked it in code: synchronized (field) { while(true) { .. I was still able to access the synchronized field directly without triggering a deadlock - whereas a getter() could be synchronized and trigger a deadlock. In any case, the article already made a strong points for immutability so you don't need to mess around with deadlocking crap.
- jayd16 2y agoThey're saying multiple things can synchronize on the same public field. Same reason you don't want to use this. Although I suppose they could mean the concept and not the keyword. A field might not be thread safe and there's no way for an object to guarantee thread safe access of to a field.
- mrkeen 2y agoDeadlocking was raised as the objection to using public instead of getter. But in regard to deadlocking, using public is strictly better than a getter. You have to take a lock in order to deadlock in the public version. In the getter version, you can take a lock without realising it and then deadlock.
- Groxx 2y agonope, sorry, that's my mistake. I'm misremembering java, it has been too long :) thanks for the correction!
- Pxtl 2y agoTo me that's just a matter of having standards that have clear requirements of what's okay to put in a getter - imho, refreshing invalidated caches (as long as they're lightweight and not like network communication) is perfectly appropriate. Anything with a side-effect that can be observed from outside of the object (creating the case where you get code just hitting setters and getters to cause side effects) is right out. I mean, Lazy<T> is a great example of use of getters.
- tyleo 2y agoI’ve written a lot of C# and have heard the proclaimed reasons. I’ve stopped doing this over time. You almost never need the interface and when you do, I haven’t found it hard to add. Maybe you do this by default if you are developing an external API for versioning reasons but that’s such a niche use case.
- lostmsu 2y agoWhen you change from fields to properties with getters and setters you break binary compatibility with previous versions, which is very bad for libraries.
- blincoln 2y agoHow much legacy code have you maintained/added features to vs. writing new code? I find that getters and setters seem like pointless overhead when I have an idea that I want to test empirically as soon as possible, but if I don't, I end up with a lot of regret years later when I have to track down all the references and update them instead of just changing code in the one place. I'm not a fan of lazy loading, but I know a lot of people are, and using the getter/setter pattern also enables fairly straightforward ways to lazy-load properties from persistent storage (or add that capability down the road if it becomes advantageous).
- almostgotcaught 2y ago> abstract it as an interface later if needed this later literally never comes. if you didn't have an ontology when you wrote the code, it never magically unexpectedly appears.
- elegantlie 2y agoI never understood this argument for statically typed languages like Java. > You can add validation for all setters, and abstract it as an interface later if needed. Sure, but why not just postpone the introduction of setters until you actually need them. 90% of time you don't, in which case we just saved a ton of boilerplate and ceremony. The 10% of time that you do, converting public variables to a setter method is about 2 IDE clicks these days. The only argument I can think of is if you are exposing a public library API, in which case you need to worry about backwards API compatibility.
- jayd16 2y agoGenerating getters is actually 2 IDE clicks that will protect you down the road. Trying to refactor fields that made it into a public API is a nightmare. If you're shipping code people use, you won't get to refactor their projects from your upstream library. Also, no one is suggesting everything needs a setter. Where is this coming from?
- alserio 2y agoIf I could I would make this two IDE clicks behind a big mean warning. In my experience people tends to autopilot it without thinking about what that entails.