The use of private scope qualifier for methods is one of the biggest barriers to reuse in Java.
I was recently searching for a way to dynamically get an instance of a java.lang.Class that represents a primitive type (basically, I needed a dynamic form of what you get when you reference something like java.lang.Boolean.TYPE). I never did find an acceptable way to do it (please email me if you know of one), but someone brought to my attention that there is a method, java.lang.Class.getPrimitiveClass(String) that appears to do exactly what I need. Great! No - the method is private, so I have no chance of ever using it.
This gets to one of my biggest peeves about the state of the Java programming art - the abuse of private, which I see as one of the biggest hurdles to reuse and extension.
A typical response to this position is that "private has a definite use and can often times be preferred as once you make something public then so it must remain for ever," but I take issue with those points.
First of all, they're forgetting about protected scope, which is much more friendly than private and provides the same level of "protection" (the notion of protection in coding is a tricky concept , as I'll get to later) in most cases.
Beyond that, I don't buy the argument about once something is public you can't change it. Very few of us are writing the kinds of code that is set in stone - refactoring is usually an option. Deprecation is your friend, too.
Actually, if you are writing some kind of code that must be set in stone, all the more reason to use protected instead of private. Because in that kind of situation (rare as it may be) you should be striving for more flexibility, not less. Private scope can only add flexibility for code in the same class; on the other hand, for increased flexibility of all other code (the clients/callers and extenders), protected and public provide much more flexibility. When you use private, you are essentially assuming that you know exactly every way in which the code might be used or extended, which is, IMO, rather short-sighted and brash.
The kind of attitude that thinks that way (must make things private because I might want to change them one day or because I know this would never be needed outside of this class) is what Martin Fowler refers to as a Directing attitude (as opposed to Enabling) and I find Directing attitude to usually be counter-productive an frustrating to work with.
Finally, I'll say this: making methods private is often justified by saying "this is implementation specific and could 'break' the code if used externally." But again I find that a bogus argument - if I subclass a class and call or override its protected methods and it does not behave how I thought (so long as it adheres to the documentation or other contract), it is not necessarily the original class author's fault. I would certainly expect testing to happen, which would uncover any false assumptions or mis-use of inherited code. Again, Directing vs. Enabling - I prefer that I'm given as many tools as possible rather than being stuck with the limited set that
some original programmer thought I would need.
OK, one more "finally": Smalltalk, probably the most pure of widespread OO languages, gets by just fine without private methods at all. I've never heard of anyone coming upon a situation where they just NEEDED them and where marking them as "intended to be" private
didn't suffice. Here is an excellent article on the subject
If you read nothing else I've written in this diatribe, read at least that and the Martin Fowler article. They are written by far more effective writers than I, and it shows.
Sorry for ranting - it's late and I was bored. Seriously, I've spent 10+ years thinking about this topic on and off, and my position is very firmly set after all that time.
Tuesday, September 6, 2005
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment