4 ms·
I 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 temperatur
by HumanDrivenDev 9y ago
I 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.
- wvenable 9y agoCelcius is definitely a getter. The name absolutely implies that it's retrieving a value because it's name is not a verb or action. Properties in C#, for example, really just remove the ambiguity in this exact situation. Is it object.Celcius or object.Celcius()? A good C# programmer would use the former. A method would be object.RaiseTemp().
- HumanDrivenDev 9y agoIt looks like I have a really different definition of "getter" than some people here. I would only call something a getter if it explicitly makes reference and effectively exposes an internal field. Just giving a method a noun name is not enough to make it a getter, in my mind. It's the "get" prefix that says 'hey there is definitely a field in here called Foo that we think we're encapsulating but we're really not'.
- sn9 9y agoWhy would you have two separate temperature values? Just have one in Kelvin that can't go below zero, and have getters and setters that translate to C/F when specified.
- HumanDrivenDev 9y agoWhat you propose wouldn't be using "getters" to me. They just sound like normal methods.
- 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.