Some reader favorites:
EJB fundamentals and session beans
Create a scrollable virtual desktop in Swing
Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API
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.
Free Download - 5 Minute Product Review. When slow equals Off: Manage the complexity of Web applications - Symphoniq
![]()
Free Download - 5 Minute Product Review. Realize the benefits of real user monitoring in less than an hour. - Symphoniq