Are getters and setters object oriented?
arkanis.de
arkanis.de
Not OO (Object Oriented) is high praise in situations where the OO solution would be worse.
All heuristics should be ignored if it suits the situation to ignore them. OO is one of many a heuristics for software design.
Sometimes a deposit abstraction is simply a waste of conceptual budget and is best avoided.
The sad thing is that way to much people think "getters and setters" when they hear "object orientation". Maybe even "Eclipse will do that for me". Needless to say that encapsulation isn't understood then, too. But encapsulation is bigger topic of it's own and would have been to much for that post.
While talking about that with other people I got the impression that just explaining the way it was meant to be does not work well. Especially if a professor and many books tell otherwise. Therefore I try to make people think for their own about the problem. Showing the problem, how it is solved and how it can be solved in other situations. I don't know if I succeeded in that.
These and other similar things drove me to hate OOP and software engineering. It seems like people always missed the proper abstraction. Then I discovered Haskell and wandered more into the theoretical aspects of computer language theory. I now have an appreciation for OOP but not the way I was taught...
function __set($property, $value){
if ($property == 'speed'){
// ...
}
}
Just write the damn setter or no setter at all but please don't use property overloading for this! function setSpeed($value) {}Of course you could throw in some runtime reflection and variable function calls to make it more maintainable. However for me it needs to pay of… I don't want to maintain such a system for just a hand full of properties. I like to keep complexity "flat" and so I often stick to the direct language features. But on large projects the code you linked could really come in handy. Thanks. :)
That it's slow might be a good point but for performance critical stuff I use D and for larger web project Ruby on Rails (where performance is a whole different topic). PHP is my tool of choice for small and compact web projects and since I try to keep them as simple as possible performance isn't that much of a concern. Anyway I did a small benchmark and was a bit surprised:
direct access: 0.276369s getter access: 0.540416s property overloading access: 0.825164s
Of course I can publish the benchmark source if someone is interested. It basically accesses a property 1000000 times adds the returned value to a sum (so that it's not optimized away… just in case).
The overhead looks ok for me. 1 out of 5 properties can be redirected via property overloading before its performance is worse than getter methods. I don't really know much about the internals of large PHP projects but I you can avoid most "empty" getter and setter methods and handle the view exceptions with property overloading performance seems fine for me.
Unexpected behavior might be a problem. However not existing properties still return NULL. The only difference is that no notice is generated… and that can be easily done with one line at the end of the __get() and __set() functions. Management of "raw" property overloading can be troublesome for a larger number of properties. However you can simply add some runtime reflection to call a corresponding getter function. But in that case I would start to think about the interface and if I might have done something wrong (in regards to encapsulation).
Having spend much time in the Ruby world I really like the kind of interfaces you can build with property overloading (like SimpleXML). For me more fluid handling like that is worth the performance cost.
However, the problem is that they are a code smell, specifically of a designer that doesn't really "get" OO. If you really have it all set up correctly, it should be rare for you to have one object do nothing more than query another object's internals, the first object should be telling the second object to do something, and shouldn't need the internals, wrapped by functions or otherwise. For all the teaching and the way it is the "official paradigm" of software engineering, very few people actually understand it well enough to use it properly. The end result is that the getter/setter user rarely finds they actually have any use, because anyone making pervasive use of them has so many other flaws in their design that they are going to have to rewrite everything anyhow.
It's a problem when people assume that getters and setters must always occur in pairs. They shouldn't! Getters can expose whatever is needed to communicate the object's external identity and state. Setters are mostly a code smell. You should pass whatever you need to a constructor and use behavioural methods to mutate the internal state after construction. For instance, a Car class can have a getSpeed(), but shouldn't (in a clean design) have a setSpeed(). It should have stepOnTheGas() or increaseSpeed().
Getters and setters make classes into little more than verbose structs.
Obviously everything I've said is aimed mainly at Java-ish languages, which was the focus of the OP's comment.
It's always a challenge to figure out when to cut off my discussion since I could go on for quite a while :) But definitely there's some cases for them.
Another example where they do make some sense is when it really is a verbose struct. A "Point", 2D, 3D, or otherwise, is generally a struct. You may have some basic methods on it, but you're going to be examining the internals of it an awful lot for anything nontrivial. (And I've fiddled with some serious OO design patterns, like layering transforms on the Point objects themselves, and the problem is that performance has always been terrible then.) You know you have one of these cases on your hands when you realize that you don't even need the getter/setter, you might just as well expose the internals, because the internals are what the object is.
(Like most, I was educated into OO dogma, and one of the earlier clues that something was wrong with it were these sorts of things that simply weren't objects and shouldn't be. A Point is just a Point, and trying to abstract the point usually isn't worth it. You very well may want to layer abstractions on top of that that provide further guarantees, and I usually stick some methods on the Points for syntactic convenience, but the Point is not itself a very good object.)
Also, if you're marshalling, you do need some sort of symmetry for getting and setting, though I prefer the getSomethingMarshable() and setWithSomethingMarshalled() (or constructWith...() ) blob approach you often see in the dynamic languages.
Not sure if "they are OO" (and what's the point?), but I think getters and setters usually are not needed and only add a lot of useless boilerplate code. Maybe in your boss's eyes it might look like you've been writing a lot of code. :)
But of course sometimes they are useful, and those times I think python's approach would be a better way. Maybe some other languages have even better ways to accomplish this?
[1] Example: child.setParent(parent) would perform parent.children.add(this)
Don't just change it, because the change seems "cleaner". You are breaking convention in a major way, and this will surely lead to worse code in the future.
Case in point: In Ruby, foo.bar and foo.bar= are never property accessors, it's just that sometimes there exists code such that foo.bar returns @bar and foo.bar= sets @bar.
Counter-examples: python properties, ruby (=, ? and normal methods), C# properties (and events), probably any message-passing language (via 'name' or ('name', 'newvalue')), lots of other languages mentioned in other comments here...
How is not using setValue, getValue "breaking converntion in a major way" then? Java, PHP, Javascript and some others do it that way. This is their convention - true. But it's far from "an OOP convention" - mainly since OOP doesn't define the syntax in any way - just some properties of the environment.