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
Page 4 of 4
For this month's homework, implement a filter decorator -- extending the TableFilterDecorator class shown in Figure 8 -- that filters high-priced items in the table shown in Figure 6.
If you look at the reader classes in java.io, you will find another decorator: BufferedReader. That class buffers reads, making it more efficient than an unbuffered reader. In light of this new discovery, you might
decide to make Example 3 more efficient, like so:
FileReader frdr = new FileReader(filename); BufferedReader brdr = new BufferedReader(frdr); // "mix in" a buffered reader LineNumberReader lrdr = new LineNumberReader(brdr);
Here are the questions from last time, followed by their correct answers:
Yes (provided you import java.io.BufferedReader)
Add:
long time = System.out.getCurrentMillis();
...
System.out.println("Elapsed time: " + System.out.getCurrentMillis() - time);
The application will run more slowly because LineNumberReader extends BufferedReader. Since line number readers are buffered to begin with, mixing in a buffered decorator will not improve performance; in fact, it will slow things down because
the buffered decorator must forward calls, which slows things down.
Thanks to everyone who sent me email after the first installment of this column. I received voluminous feedback with many interesting suggestions. As a notable example, Mark Riggle wrote:
I have an idea that you may already plan to incorporate. As you say in the article, object composition is preferable to inheritance. Many of the Gang of Four patterns reflect this concept by using delegation to pass a method to an object that will do the work. Strategy and Decorator are certainly two such patterns. The problem for languages like Java is the required dispatching methods. The decorator object must implement the methods of the object it is decorating, and most will likely just directly pass on to the decorated object. This is needed so that the client code is left unchanged. So whenever the decorated class changes its signature, the decorators must also be updated. This is a coupling problem solvable using some of the dynamic features added to Java. The most important one now is the dynamic proxy. Because many of the methods added to classes are merely forwarding calls to a delegated object, the dynamic proxy lets you do exactly that without actually adding the method definitions...
Thus, I think that the dynamic proxy and pattern use in Java go hand in hand, and a discussion on patterns needs to include a discussion on the dynamic proxy.
Mark is absolutely correct. Since JDK 1.3, Java directly supports the Proxy pattern. The Proxy pattern is closely related to the Decorator pattern, and is the topic for my next Java Design Patterns installment. In that article, I will show you how to use the built-in JDK support for the Proxy (and Decorator) patterns to implement the sort decorator example from this article.