Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Are getters and setters object oriented? (arkanis.de)
20 points by rb2k_ on Dec 19, 2010 | hide | past | favorite | 29 comments


Getters and setters aren't object-oriented, and for that matter they aren't good examples of encapsulation, either. It varies from case to case, but cherry-picking, if I have an account, I don't care whether I write account.balance = $100 or account.setBalance($100). What I ought to be doing is defining semantically rich methods such as account.deposit($100).


I agree that getters and setters aren't object oriented. It was the whole point of my blog post to make people think about that. It wasn't written for people who already understand that, though… otherwise it would be quite a bit shorter. ;)

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.


Well, I upvoted the article and I think I tweeted it as well. So it passed the "It made me think" test, thank you!


What you ought to be doing is making trade offs that make sense for your situation without following any particular religion.

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 university I went to for my undergrad very much drilled it into us that Getters and Setters are the thing to do. I got out into the working world after that and it seems everyone else was taught the same thing. When I actually came to change things it never seemed to help and I always had to rewrite mountains of cruddy things. It came to the point that I would automate so much of the code generation using python. If I can automate it with a tiny fraction of the code then there is certainly something wrong with the design and premise.

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...


And ruby has a nice solution for this. It allows methods ending in = to act as setters clean overrides and provides methods (attr_accessor and friends) to generate vanilla getters and setters for you. You can access instance variables via instance_variable_get but that's not recommended.


Objective-C is similar -- you have "setters" and "getters", but since there is no direct ivar access and you have the convenient @property syntax, you end up with a reasonably similar end result.


There is direct ivar access, but no sane person uses it outside of the class itself :P


I seem to recall the whole getter/setter thing becoming popular with JavaBeans (note not EJBs). Java didn't have a nice way of identify something as a "property" that could be exposed graphically through an IDE interface so adopted a syntactic convention. This soon became adopted as "best practice" even though I suspect 99.9% of getters and setters do nothing but expose an underlying field - as with most programming "best practices" very few people can actually tell you what the benefits are supposed to be.


The sad thing is all JavaBeans needed was named arguments to the constructor rather than relying on setter names. It's a lot more complicated for every class to let instances be created in a mostly-uninitialized state, relying on a bunch of setter calls in an unspecified order to make the instance actually usable. For one thing, there's no language-supported way to make a setter mandatory, you can't do any better than blowing up at runtime if it wasn't called.


Spring prefers setters and getters (the constructor support is not as good), and this makes it harder to communicate what is optional configuration with defaults and what is essential.


There's a more interesting point to be made about getters and setters than the article offers. In my opinion, getters and setters are a little stinky because by nature they expose internal attributes of the class, even if they wrap them up in method calls. See http://stackoverflow.com/questions/565095/java-are-getters-a... .


The entire point of a getter/setter is to hide the internal attributes of the class behind a layer you can later change, and therefore they aren't "actually" exposing the internals, they just happen to be implemented that way at the moment but may later change.

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.


You almost always need to have a client object observe the state of an instance - clients need to marshall it for the network or log some information about it, etc. So getters make sense.

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.


"You almost always need to have a client object observe the state of an instance - clients need to marshall it for the network or log some information about it, etc. So getters make sense."

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.


Using property overloading to implement getters/setters in PHP is terrible practice. It's slow, makes the code hard to manage and introduces unexpected behavior.

      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) {}


I would be interested in why it is considered a terrible practice.

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.


His implementation leaves much to be desired, but there are better ways of doing it.

http://pastebin.com/JiEXp6Za


The example is the most simple way I could think of. It should only show that is is possible not what is the perfect solution (if there is any).

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. :)


IIRC the property overloading in PHP is slow, especially compared to hardcoding the getters and setters, so you're better off hardcoding them. Property overloading in itself is a neat feature for syntactic sugar, for example an object with (semi-)dynamic properties like in an ORM. Other properties of classes, those nog generated on the fly, are better off with the getters and setters written out.


It's somehow unbelievable how long this getter/setter convention has been used (at least?) in java - People mindlessly generating them with their IDE - and nobody cared to question it and/or think of a better way before.

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?


Getters and Setters violate encapsulation just as much as accessing properties directly, so I don't bother with them unless I'm forced to. In languages like C++ they can make sense due to a need of allocating and freeing memory of things within the object, but it's still not OOP. What you have when you're using getters and setters is a fancy struct with methods, not an OO class. (There is a significant difference.) Stop pretending you're not using a struct and just access things directly or start following a 'draw thyself' model. Both approaches work.


I very much agree, but saying it in such a way won't help others to understand that. That is persons that haven't understood the significant difference right now.


Getters and setters are a lip-service to the actor model.


One of the issues the whole setter/getter convention creates is that, for instance, I'm now reluctant to write a setter method that does more than just set the field value [1], because some other programmer or some tool might expect that it is no more than a property mutator.

[1] Example: child.setParent(parent) would perform parent.children.add(this)


Languages are based on widely understood conventions. If it looks like I'm writing to or from a variable, then let that be what happens, because that's how 98% of programmers will understand it to be.

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.


Yes, but if a language provides a mechanism whereby what look in other languages like property accessors can actually be implemented as method calls, then in that language, 98% of programmers ought to--like true scotsmen--expect that it might be a variable and then again it might be a method call.

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.


If you're talking about a narrow view of what new compsci (with a poor programme) person might know (== only java) - yes, these are understood conventions, although even that is not completely true.

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.


getter and setters are not necessary, but offer nice syntactical sugar to a language.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: