8 ms·
If you have a temperature class with a celsius field and change the internal representation to kelvin you have to update all client code to call a conversion me
by Tarean 9y ago
If you have a temperature class with a celsius field and change the internal representation to kelvin you have to update all client code to call a conversion method. C#s syntax sugar allows you to slot in the conversion method without a breaking change but it screws with the cost model of field accessing when used unresponsibly. Java doesn't have it so you would have to hide everything behind getters if you don't want to tie yourself to a representation.
Whether a data class should touch enough code to make the transformation a burden is another matter, though.
- HumanDrivenDev 9y agoI appreciate you thinking of an example, but I guess I find it a bit convoluted. Couldn't you also refactor that by changing the constructor of your temperature class so it converts things to Kelvins, rather than converting it every time you call the getter?
- Tarean 9y agoSure, but every field access like Temperature temp = Temperature.fromCelsius(13); ... System.out.println(temp.celsius); would have to be changed to System.out.println(temp.getCelsius()); when the internal representation is changed.
- HumanDrivenDev 9y agoI get what you're saying, but at the same time I don't understand how you'd implement the class and why. class Temperature { public final double celcius, kelvins; Temperature(int celcius, int kelvins) { this.celcius = celcius; this.kelvins = kelvins; } public static Temperature fromCelcius(int c) { return new Celcius(c, c - 273.15); } } What's wrong with that approach, and how would you do it?
- goflyapig 9y agoThis only works if your class is immutable. If a client sets either of those fields, they will now be out of sync.
- HumanDrivenDev 9y agoWhy have a mutable class to represent temperature - a simple value class with two fields? Why not just construct a new Temperature? I mean if performance was an issue, you'd just use plain doubles instead, right? I'm open to the idea that setters do have a use case, but I'm not seeing one here.
- xapata 9y agoHow about a class that stores temperature and the current state of the satellite? It's easy to come up with circumstances where requirements change.
- HumanDrivenDev 9y agoThen I would implement it as a "real" class, not a data one. class Satellite { Coordinates coordinates; double celcius; /*** constructors, etc ***/ public double Celcius() { ... } public double Kelvins() { ... } public void Move(...) { /* modifies state */ } } Note how none of the methods make any mention of low level operations like setting/getting internal fields. You could make the argument that I do have a getter there, Celcius. But at the risk of pedantry I'd argue it isn't so. The name doesn't imply that it's retrieving the value of a field - ie the internal representation could easily change to Kelvin or Fahrenheit - where as "getCelcius" definitely tells me there's a field there called Celcius. Hmm, after writing that I wonder what the definition of a setter actually is. I have no problem with a method that just returns a field, as long as it doesn't go out of its way to tell me that's exactly what it's doing. Maybe the distinction I am making is too subtle.
- 9y ago
- arthur_pryor 9y agowhat if the constructor's not the only place you can set the value?
- HumanDrivenDev 9y agoThis is a bit abstract to me. I don't tend to write mutable classes. And if I do mutate fields, it's for a "reason" (and I'll name the method after that reason). If you feel like it, write out how you'd implement the class and why. I posted a fairly strong opinion, but I'm happy to have my mind changed.
- arthur_pryor 9y agosure, ok, if you only write immutable classes, by definition you never need setters, right? i won't defend mutable classes (i won't decry them either), because i haven't personally thought tons about the benefits of immutability. i mean, i can see a lot of reasons why it's a good thing to shoot for, and i think it's a thing i often try to shoot for. but people often write mutable classes, or must maintain mutable classes written by their predecessors. in which case, setters can be nice. or they can be annoying boiler plate. seems like a case by case thing to me. i think the getter/setter thing does often feel needlessly verbose, and so i upvoted your original parent comment. but "setters are always bad and i don't understand why anyone would ever use them" seems like a needlessly hard-line sentiment, IMO.
- HumanDrivenDev 9y agoIf you have a mutable class, and you're modifying its fields, you're doing it for a reason, right? Often it's part of a larger operation. So why not name the method that mutates the field after that reason. I got away from thinking about "I am altering the internal representation of this struct + vtable" to "I am sending a message to this opaque thing and I don't really care how it's done when I'm outside the black box". > but "setters are always bad and i don't understand why anyone would ever use them" seems like a needlessly hard-line sentiment, IMO. I have a strong opinion because I read some compelling arguments, thought about a lot, stopped using setters, and the quality of my code improved. I don't see a need to moderate my opinions on programming, especially when that's what I really think. Again, happy to be shown a great counter example and admit I was wrong.
- chubot 9y agoFWIW, I've been writing software professionally for more than 15 years, and I've literally never come across this problem. It feels contrived to me. However, there are many different types of programming, so I'll concede it the technique could be useful in domains I'm not familiar with. But if there any such situations, then I don't think they explain the wide popularity of getters and setters. I rarely use getters and setters and it's never been a problem. I also don't use public fields unless the class is only public fields (and the language doesn't have some kind of record/tuple type), as another commenter mentioned.
- hrktb 9y agoI think the popularity of getter and setters come from a mix of dozens of small problems to solve. Protection from internal representation change is one. Expliciting what can be done with a property is another (i.e force write only or read only properties by only exposing a setter or a getter). Exposing “virtual” properties that are a combination of “real” properties (i.e. exposing a string representation of a price with a currency for instance, where both the price and currency are independant properties). Spying on getters and setters also helps for testing. And so many other potential uses. Each use case is not a big deal on its own, but there is enough chance to hit at least one of the potential use case for at least some of the objects that autogenerating getter and setters for basically everything is seen as a good practice. Also no one gets fired for putting getter/setters, the reverse could be true. I personally prefer contexts where I don’t have to care so much about all the above (this means less protective programming in general), but in a lot of enterprisey applications generating getter/setter everywhere is just a way of life.
- coredog64 9y agoHow about this non-contrived example: Certain data types (Array, Java.util.Date) expose private information if you just blindly return your instance variable to the caller. Setting can be dumb, but you may want to create a defensive copy to hand back on get. C# syntactic sugar makes that apparent to the reader.
- deleted 9y ago[deleted]