Oct 16 2005
Violating Encapsulation
One of the core tenets of object-oriented programming is encapsulation. It’s one of OO’s most powerful ideas. More powerful than inheritance. Unfortunately it’s also one of the most ignored.
In “OO in One Sentence: Keep It DRY, Shy, and Tell The Other Guy” Andy Hunt & Dave Thomas (The Pragmatic Programmers) talk about good OO code being shy:
“The best code is very shy. Like a four-year old hiding behind a mother’s skirt, code shouldn’t reveal too much of itself and shouldn’t be too nosy into others affairs.
But you might find that your shy code grows up too fast, shedding its demure shyness in favor of wild promiscuity. When code isn’t shy, you’ll get unwanted coupling.”
Something I see all the time, on every team I’ve been involved with, is code like the following (classes are generalized from examples):
MyThing[] things = thingManager.getThingList();
for (int i = 0; i < things.length; i++) {
MyThing thing = things[i];
if (thing.getName().equals(thingName)) {
return thingManager.delete(thing);
}
}
This code is tightly coupled to the implementation of myThing in that it gets the name property, knows that it’s a string, etc. This is a classic approach from the old days or procedural programming. It is NOT OO.
How about:
MyThing[] things = thingManager.getThingList();
for (int i = 0; i < things.length; i++) {
MyThing thing = things[i];
if (thing.isNamed(thingName)) {
return thingManager.delete(thing);
}
}
This code still knows the details of myThing. Why should it? All it should know is how to ask a thing manager to delete a thing given its name:
return thingManager.deleteThingNamed(thingName);
thingManager is closer to MyThing, in fact they’re likely packaged together, so it’s not as bad for it to have somewhat more intimate knowledge of MyThing.
This is just one example of the approach of treating objects like new age data structures: Ask an object for information about its state, process that, make decisions based on that, then do something to/with the object.
In the above example, the code
- asks the ThingManager for its list of Things
- iterates through those Things
- asks each one for its name
- checks if the name is what it is looking for
- if so it asks the ThingManager to delete that thing
The proper approach is to ask the thingManager “Delete a thing named this if you have one. Let me know if you were able to do that.”
As a side note, writing code this way makes it much more understandable.
Do you write code like the first snippet? If so, you’re not doing OO! Stop telling people that you are. Or better, start doing OO. Better still, get your whole team doing OO.
Tags: code oo