6 ms·
"I still stubbornly believe the whole “private members accessed via accessors” thing in java is bullcrap for internal projects. It adds piles of useless boilerp
by pigs 15y ago
"I still stubbornly believe the whole “private members accessed via accessors” thing in java is bullcrap for internal projects. It adds piles of useless boilerplate code for absolutely no gain when you can just right click a field and chose “add setter/getter” if you NEED an accessor in the future."
Is this a controversial stance? It seems like common sense, unless I'm misunderstanding something.
EDIT: To clarify: I assume he's saying "don't add accessors by default for all private members unless you need to, because you can always go back and add it if you really need it", which is common sense for any project, external or internal. I'm pretty sure he's not saying "don't add accessors, just use public members", which is controversial, IMO, even for internal projects.
- jarrett 15y agoControversial might be too strong a word, but there is a counterargument to be made. Suppose you have a member named "x." Someday, you might want to stop storing x, and instead make it a calculated value. At which point you'll need a method. Or, when setting x, you may someday want to increment a counter, or transform the input data, or take some other action. Again, you'll need a method. Yes, it's very easy to add an accessor later. But then you'll most likely have to edit every line of code that accessed the now-defunct member variable. Your IDE may make this easy, but I'd still prefer not to have to do it. That's not to say writing accessors is always the best choice. I'm just saying there can be good reasons to do it. Like all things in software engineering, there's no one-size-fits-all rule about this. Notch is right about the bloat accessors create, so you have to weight the advantages and disadvantages yourself in each case.
- lclarkmichalek 15y agoA lot of languages have constructs that allow changing an attribute into a method call transparently (@property in python and D)
- jiggy2011 15y agoI think this idea is that you can use "properties" rather than public class variables. Then you can convert your public vars into properties at a later date. This means that you will not have to (necessarily) rewrite your code as the language knows that a = myobj.myvar now should call getmyvar() in the containing class and: myob.myvar = a should call setmyvar(a) , I know that C# certainly allows this.
- esrauch 15y agoC# allows it but but Java doesn't have this. Hence why it's standard operating procedure to just use setters from the beginning, because it might be nontrivial to update all references.
- jiggy2011 15y agoPlay! framework allows you to use getters and setters with public members as you would in C#. Not sure how this is implemented.
- aaimnr 15y agoSpring Roo does the same through the use of aspect programming (code generation, essentially - it generates the boilerplate behind the scenes).
- cstuder 15y agoNo. C# and Objective-C (And I assume similar languages too) can have public accessors which are not used like function. No need to add ()'s everywhere.
- InclinedPlane 15y agoThe way current C# does accessors / properties is just about perfect, I wish more languages would adopt it.
- masklinn 15y ago> The way current C# does accessors / properties is just about perfect As far as I'm concerned it's quite far from it, because C# still allows public fields, properties and fields are incompatible, properties and methods are separate and Microsoft specifies different naming conventions for fields on one hand and properties & methods on the other. Perfection is Smalltalk's way of doing it. And in a syntactic line closer to ALGOL, Ruby is about as good as it gets: no public fields, "properties" are normal methods (setters have a little bit of syntactic sugar, but not much) and auto-generating a bunch of getters, setters or both is a class-level method call.
- de90 15y agoWhat is wrong with different naming conventions for fields vs. properties, and methods? It makes it immediately obvious what is what at a glance. *Honest question - I first learned programming with C#, and so those conventions seem 'correct' to me.
- masklinn 15y ago> What is wrong with different naming conventions for fields vs. properties, and methods? It makes it immediately obvious what is what at a glance. Which is precisely one of the problems of properties in C#, it makes fields and properties look and feel extremely different from the outside which violates the uniform access principle. As I noted, ideally C# should not have public fields in the first place.
- Sufrostico 15y agoIMHO most software 'service life' it's not long enough to justify the annoyance of the accessors. Most software are outdated after a couple of years. But I still think that accessors are a must if you know that the software will be immortal (like Internet banking applications)
- figglesonrails 15y agoThat's a pretty brutal stance. :| I can't say I know the average shelf life of a software component in various languages, but I can say that at least things like Java have managed to justify their use of accessors by that metric. Maybe the focus should be on writing less throwaway code than deciding whether to "invest" a few extra minutes or not on accessors.
- Garbage 15y agoThat is an understatement. I am currently working on a code which was written at 10 years back. And that code is still running on production server. tl;dr; Usually enterprise Java applications does have long "service life".
- dextorious 15y ago"""Most software are outdated after a couple of years.""" You'd be surprised. Tons of code runs in production, even in the latest of shiny systems, that was written 10 and 20 and 30 years ago -- either in whole or in parts, refactored etc. From 1986's NeXT OS that is now OS X Lion and iOS 5, to Bill Joy's TCP/IP, to Emacs. And tons of enterprise/banking/financial/military systems use ancient code, even 70's COBOL...
- akg 15y agoI think most companies have tons of legacy code that is stilly lying around and in production use. When I was at Dreamworks Animation, we were still using tools written back in the 1980s to create animated features; albeit we kept improving on it whenever it didn't fit the bill.
- figglesonrails 15y agoCode bloat, at least _compiled_ code bloat, tends to be less on an issue with trivial accessors in C++ since they are generally inlined, but it does add a lot ()s. For non-trivial accessors, yeah, you can inline a lot of copies of that logic. Vector v1(v2.getX(), v2.getY(), v2.getZ()); vs Vector v1(v2.x, v2.y, v2.z);
- tikhonj 15y agoGosu supports a property syntax that lets you use = to assign things to get/set method pairs. In fact, when you load existing Java code, it replaces getFoo() and setFoo(foo) methods with a property. This makes the code neater and enforces the abstraction--the user of the property does not need to know whether you've implemented it as a simple variable or a complicated method. A bunch of other language let you do this as well.
- haldean 15y agoPython can do this: http://docs.python.org/library/functions.html#property http://docs.python.org/library/functions.html#property
- dextorious 15y ago"""Yes, it's very easy to add an accessor later. But then you'll most likely have to edit every line of code that accessed the now-defunct member variable. Your IDE may make this easy, but I'd still prefer not to have to do it.""" Easy is an understatement. It's 2-3 clicks away in Eclipse.
- deleted 15y ago[deleted]
- jebberjeb 15y agoWho was talking about Scala?
- angersock 15y agoEh, using protected/private members is one of those things that makes sense only insofar as you are paranoid that you can't just access internals directly. That said, consider the following. I've got a renderer that accepts a sprite to draw. Version 1: I pass the sprite object to the renderer, and the renderer gets the texture contained in the sprite and draws it, scaling it according to the sprite's size and position public members. I then decide that all of my sprites draw slightly differently (different scales/glow effects/color tint/whatever). Version 2: I pass the renderer my sprite, it gets the size and render settings members from the sprite, and then draws it. Oops! I now decide I want a hierarchy of sprites, so that I can add hats. Version 3: Same as version 2, but in the draw routine now the renderer asks the sprite for its parent to calculate its position and size, and now I've got more renderer code and more sprite code. I can't just use the exposed position member of the sprite--it has context and logic behind it that must be done. Oh wait, I have a problem in which the sprite glow might change depending on how many times its been drawn. Version 4: The renderer now has to keep track of how many times it's drawn a sprite. My renderer is getting a bit chunky now. Did I mention scale should change according to time but also the sprite's velocity? Version 5: Renderer grabs these variables directly, and does all that other stuff too. ...and that now I want to let that scale be overridden by a isConstantSize flag on the sprite? Version 6: aaaaaargh ...and that now the sprite can decide it wants to defer to a parent sprite's settings sometimes? Version 7: what did i do to deserve this? ~ Proper encapsulation and use of accessors is clearly a sign of paranoia. That said, as your code evolves, you might find that this paranoia is completely justified. Hiding queries behind interfaces lets you future-proof them and trivially add more advanced behavior and hooks. Even when you are working by yourself on an internal project, you are never working alone. You are also working with your future self, and that person is guaranteed to want something different from you and to make assumptions that you are not.
- angersock 15y agoOh, and for good measure--everytime you force yourself to use an accessor, you are providing the opportunity for somebody down the line to add debug and validation code. Or to add locking and critical sections. Or replace a dumb get and recalculation with caching. Or replace caching with a dumb get. Or a database access. This flexibility is not something you might think you need. You might also never need to debug your own code, or check your assumptions about variables, or track who is accessing what when. (for what it's worth, I don't use protection for data members of Plain-Old-Data types [say, messages or vectors] very often--they're too dumb to deserve this sort of extensibility or cost)
- deleted 15y ago[deleted]
- kalak451 15y agoThe getter/setter stuff in java is a huge waste of space and time. However, at least in the enterprise space, all of the tooling and frameworks assume your code follows the java bean naming conventions. For this reason alone I always make sure all my classes follow the pattern and whenever I train new developers I make sure they get a large amount of experience building out bean definitions and understand how much time is saved with Spring and Hibernate as long as the conventions are followed. But yeah, its a bunch of ridicules, generated spam.
- pigs 15y agoJoshua Bloch in Effective Java argues that the java bean is an anti-pattern and should be avoided.
- figglesonrails 15y agoCool story, bro. (Mime aside, do we get to hear what the argument was?)
- pigs 15y agoThe crux of the argument (and most of the book for that matter) is that you want to avoid mutability whenever possible. Adding setters for every field by default means mutability is the default mode for your application. Adding getters for every field by default means you lose any advantages of encapsulation. At one time, Java Beans were a heavily marketed pattern by Sun. Joshua Bloch came along and said "hey, this is a bad pattern" (and maybe others, but he's the one I always think of).
- jiggy2011 15y agoWhy does everything have a getter/setter by default? That is a pretty horrible anti-pattern, is it something to do with being able to serialise the state (including internal state) of the whole object?
- 15y ago
- koenigdavidmj 15y agoThe problem is when those getters and setters have other effects (maybe invalidating a cache?). In Java, it's considered best to just go ahead and add the getters and setters first, so that when you need to add these side effects later you don't have to modify lots of code using your library (if that is even possible). Languages like Python make this unnecessary since they have first class properties: # Old class Foo(object): def __init__(self): self.x = 0 foo = Foo() foo.x = 1 # New class Foo(object): def __init__(self): self.__x = 0 @property def x(self): return self.__x @x.setter def x(self, val): self.__x = val do_other_stuff()
- pigs 15y ago"In Java, it's considered best to just go ahead and add the getters and setters first" I don't think this is true. I'll concede that it may be a requirement for certain things like an ORM API, but in the general case, it's bad practice. The mere act of adding a getter violates immutability.
- esrauch 15y agoAll of your objects are immutable? Besides that's hardly an argument for having public members, being able to remove the setter or getter (or conditionally throw exceptions in them) is one of the exact reasons why you write them. The intent of the comment you are replying to "best practice is if you would add a public member, instead add a private member and a setter & getter" which is generally correct.
- pigs 15y agoYep, I think I misread his comment, which was probably a misread of my original post, which I'll admit wasn't stated very clearly.
- masklinn 15y ago> The mere act of adding a getter violates immutability. Uh what? No it does not. Writing stupid getters (or classes) might, but writing getters does not "violate immutability". Naturally, getters are not of much use if all your fields are final and hold immutable objects, but the latter can be tricky in many OO languages. Getters significantly improve the situation there, by providing a point at which you can clone your internal state and return a copy, letting you keep your object immutable even if you have mutable fields (of course this assumes you can deeply copy all your mutable member objects)
- bitops 15y agoIt's a bold stance, at least. From my experience, it's idiomatic Java and just one of those things you have to do. In practice, it's useful because it allows more easily for instrumentation later on. And you can easily throw a "synchronized" on the method if necessary.
- teyc 15y agoNot that controversial in Python. GvR's attitude is use conventions, and "after all, we are all consenting adults. :)" I found this worked very well in real life.
- liquidcool 15y agoWe just discussed this at our local JUG meeting last night. My take is that accessors are popular in Java because most popular frameworks (esp. Spring) have a heavy reliance on JavaBeans. Once you start using objects everywhere as JavaBeans, you've no choice but to add them. And the IDE makes it trivial. Yes, there's constructor instantiation in most DI containers, but it's not frequently used. I do agree that most modern languages have a much more elegant solution for this.