Steve Yegge started blogging again recently and his second post back (which is almost a month old by now) is essentially a parody of Java’s access specifier system and the prevalence of the “private” attribute. The debate over public vs private comes up every now now and then in object-oriented programming and has its fair share of people on either side of the line. So when Steve suggested that private just go away (or seemed to suggest that anyway) he of course got attacked with counter-examples and all sorts of cases where private is helpful.
Saying that everything should be public is certainly an idea that takes getting used to. It’s like saying that you should publish the details of your drunken escapades on your blog. It’s unsettling, but then again, the pictures are probably already on Facebook anyway. I think there are two issues here — one is for fields, and the other is for methods.
Though Steve seems to say that fields should be public (or have getters and setters on them), I personally tend to go the other way: fields should be private by default and only accessible through getters and setters. I like the way Ruby does it — everything is private by default but the accessors are generated by metaprogramming, so you don’t have the junk lines of getWhatever and setWhatever that you do with Java. Direct field accesses like Java and C++ allow are just bad ideas.
For methods things are the other way around. Firstly, I don’t like the idea of invoking methods on an object. I far prefer the Smalltalk notion of sending messages to objects and having them respond. I think it’s a far better conceptual model than methods and the private/public debate goes away in that model. If your object responds to methods, then being able to use private and public means that the object knows of and cares about where about the message is coming from. However, this breaks encapsulation. Ideally an object should respond to a particular message the same way irrespective of where the message comes from.
But, you say, what of the real world where ideals don’t necessarily hold? Hmm… let’s see what happens to software development under the assumption that all your methods and functions are callable from outside. To start off, you have to be careful about what parameters your methods take. You can’t assume that they’ve been pre-sanitized which means that either you’ll have to check them yourself or fail cleanly (and maybe send a stern warning up the chain). This may be a bit annoying, but I’d say it’s on the same level as dynamic typing — you’re never 100% sure of what type the arguments are so you take appropriate measures.
Now let’s talk about safety. One of the arguments in favor of private is that you don’t want methods to be abused and put the object in an unusable state. Again, I don’t think this is as big of a problem as it’s made up to be. It just involves rearranging where checking occurs. Presumably, if you have a private method that makes delicate changes to your object, you have a public method somewhere else that approves the changes and then calls said private method. Why not put the approval inside the private method and dispense with the public method entirely? If you want to make a change to an object, call a method to do it. If it works, fine. If not you get an error back.
I should make it clear at this point, that I don’t have any real world example to back up my claim (at least no examples that aren’t hopelessly contrived). What I’m talking is refactoring to meet a design constraint — that of total publicness. People will kick and scream and say that it breaks their careful separation of functionality into methods, but I think it’s just a design pattern, like dependency injection for example. And the trade-off to that is probably more flexible, more powerful software systems.
If everything is public (and designed from the ground up to be public) you start writing code that’s meant to be used by other code. Which in turn makes it easier to use and extend your code. I think you’ll eventually end up with something like Emacs — lots of public functions that do useful things to an object (the text in the editor) and an awesome array of functionality made possible by using these public functions. There is a fundamental change in programming and building ideology that needs to take place. With full publicness you can’t have a nicely bureaucratic language like Java. You’re going to end up with something that’s far more open and flexible like Ruby, Python or *shudder* Lisp.
I think that a lot of the heightened discussion surrounding Steve’s suggestion stems from the nature of the Java language. It’s certainly meant to be used by large corporate teams and is designed to stop programmers from hurting themselves (or stepping onto someone else’s turf). “Bureaucratic” is perhaps the best way to describe the language. If you take out private from a language like that, you lose most of its raison d’etre. So is private a good thing? Probably not. Does it need to stay in Java? Probably.
I’d like to reiterate that I think that message-passing is a superior way to think about object-orientation and it makes the public/private debate unnecessary. That’s why the language I’m building for my thesis will have message-passing. I’m also stealing Ruby’s private-by-default and metaprogramming for accessors.