B669: Personalized Data Mining and Mapping
Think Like An Object

 

The central idea behind object-oriented programming is to protect us programmers from ourselves. Face it: we're lazy, shiftless, and forgetful. To help us not make quite as many silly mistakes as we usually do, Java lets us make each object responsible for its own state and behavior. Unfortunately it doesn't force us to do that.

Many problems result when we stray from the straight-and-narrow of having each object be the sole controller of its own state and let other objects arbitrarily change that state without getting permission from the owner object.

Good object-oriented programming is simple if you remember the following rule: always put yourself in the object's place. You're an object and you have variables and methods (state and behavior). Other objects exist. They work with you to do complex things. To do so, they will ask you to do things and you will ask them to do things.

Thinking of yourself as an object, the simplest step towards the goal of utter encapsulation is to keep all your variables and methods private. Of course, that's too extreme a solution since then no other object can ask you to do anything, so you're effectively outside of the system you're supposedly a part of. There can be a role for such an entity in some types of Java programs though (and I'll discuss it in a future Penny), so we won't completely rule out the possibility entirely.

Short of that extremity, however, you can make some of your methods public as the need arises, but never make any of your variables anything other than private (or at least protected). Public (or package) variables have no way to defend themselves against arbitrary changes by outside objects. Once you make a variable public it is helpless against the barbarian marauders.

What's the point of defining a variable private, you might ask, if we are going to also have public set and get methods for that variable? Making the variable public and getting rid of the public methods is functionally equivalent, easier to type, and shorter and simpler. Besides, public get and set methods provide no extra protection to the variable than simply making it public in the first place, so why bother?

The reason is that stupidity is everywhere; it's the universe's most prevalent element, even more so than hydrogen. Making all variables private (or, at worst, protected) helps you to protect yourself, which makes your program more robust and more flexible, because:

* If tomorrow you decide to take away the variable entirely, perhaps replacing it with some other variable or a computation, or if you decide to simply change its type, nobody's code has to change but your own. Changes are localized to the nearest encapsulation wall (the boundaries of your class---or, in the best case, the enclosing method). This locality makes it easier to find and localize changes and to identify and track down bugs.
 
* By directly referencing your public variables other classes are tied to you. Any change in them may require a change in you and any change in you may require a change in them. The more coupled the classes are, the more complex the program is, since anything may influence almost anything else.
 
* Once you've protected your variables with a shell of public getters and setters you can protect them even more. For example, by giving a variable public accessors and private setters, the variable becomes read-only to the outside world. Anyone may read the value of the variable, but only objects of the class itself may alter it. (The flip side of course is write-only variables, which can be written to but not read by outsiders; although such a variable seems pretty silly, there might be a use for it somewhere.)
 
* With such a shell you can add code to count the number of times the variable is access or changed, and otherwise control how and when it is to be used---and even who it is to be used by.

Protecting your class's variables with a shell of public getters and setters gives your class control of its own destiny. The shell gives you power, safety, and control. A shell of getters and setters around a private variable gives you freedom and takes away the possibility of damage caused by ignorant users. None of that is possible with a naked public variable. Encapsulation simultaneously protects you and it protects them.

If you're now thinking that only a very stupid programmer will misuse your public variables, always remember that all programmers are stupid programmers. That includes you. It includes me. It includes everyone. We all make mistakes---it's only a question of how often we do so. In the face of the immensity and insane complexity of a large computer program we're all idiots. The less that programmers have to think about how to use your code the more likely they are to use your code correctly.

Finally, if you're thinking that no matter how you protect yourself some nitwit can always find a way to undo the protection and mess things up, you're probably right. But by that reasoning we should give loaded handguns with the safety off to newborns because they could have accidentally crawled up to the gun cabinet, picked the lock, gotten out the gun, loaded it, flipped the safety off, turned it on themselves, and fired. Protect your users by protecting yourself.