Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
It's a 25-year-old principle of object-oriented (OO) design that you shouldn't expose an object's implementation to any other classes in the program. The program is unnecessarily difficult to maintain when you expose implementation, primarily because changing an object that exposes its implementation mandates changes to all the classes that use the object.
Unfortunately, the getter/setter idiom that many programmers think of as object oriented violates this fundamental OO principle
in spades. Consider the example of a Money class that has a getValue() method on it that returns the "value" in dollars. You will have code like the following all over your program:
double orderTotal; Money amount = ...; //... orderTotal += amount.getValue(); // orderTotal must be in dollars
The problem with this approach is that the foregoing code makes a big assumption about how the Money class is implemented (that the "value" is stored in a double). Code that makes implementation assumptions breaks when the implementation changes. If, for example, you need to internationalize
your application to support currencies other than dollars, then getValue() returns nothing meaningful. You could add a getCurrency(), but that would make all the code surrounding the getValue() call much more complicated, especially if you persist in using the getter/setter strategy to get the information you need
to do the work. A typical (flawed) implementation might look like this:
Money amount = ...; //... value = amount.getValue(); currency = amount.getCurrency(); conversion = CurrencyTable.getConversionFactor( currency, USDOLLARS ); total += value * conversion; //...
This change is too complicated to be handled by automated refactoring. Moreover, you would have to make these sorts of changes everywhere in your code.
The business-logic-level solution to this problem is to do the work in the object that has the information required to do
the work. Instead of extracting the "value" to perform some external operation on it, you should have the Money class do all the money-related operations, including currency conversion. A properly structured object would handle the total
like this:
Money total = ...; Money amount = ...; total.increaseBy( amount );
The add() method would figure out the currency of the operand, do any necessary currency conversion (which is, properly, an operation
on money), and update the total. If you used this object-that-has-the-information-does-the-work strategy to begin with, the notion
of currency could be added to the Money class without any changes required in the code that uses Money objects. That is, the work of refactoring a dollars-only to an international implementation would be concentrated in a single
place: the Money class.
Most programmers have no difficulty grasping this concept at the business-logic level (though it can take some effort to consistently think that way). Problems start to emerge, however, when the user interface (UI) enters the picture. The problem is not that you can't apply techniques like the one I just described to build a UI, but that many programmers are locked into a getter/setter mentality when it comes to user interfaces. I blame this problem on fundamentally procedural code-construction tools like Visual Basic and its clones (including the Java UI builders) that force you into this procedural, getter/setter way of thinking.
Archived Discussions (Read only)