|
|
09.25.2004 |
|
||||||||||
| Loose Coupling, Part 3 | ||||||||||||
I'm quite interested in the concept of software components and how those ideas can be applied to Java code. Thoughts or ideas I have on this subject get dropped here for the benefit of humanity and my own hubris.
|
I know when I promised My Readership some ideas on the subject of loosely coupling components, I thought that by now I would have been running off into the weeds of Reflection or the heights of Aspects. But there are still many more, simpler ways for two components to talk without having too much interdependencies. Many of these revolve around one or more design patterns, and I thought I would briefly list some of these with a view towards loose component coupling. If you want a good treatise of these design patterns and their use in more general cases, I suggest checking out David Geary’s series for JavaWorld, Java Design Patterns. I’ve already mentioned the use of the Factory design pattern. The idea here is that you can get an instantiated object without specifying its exact name. A great example of this is found in the Apache Jakarta’s project, Logging Commons, which allows you to write logging code without actually specifying which logging engine you are going to use. You’re code would look like this: Log log = LogFactory.getLog("myClassName");
The However, you are dependent on this Jakarta library. In your own code, however, you state that a factory will return an object that implements a particular interface. Which class your factory uses is for you to determine. You can have the factory accept a string description, or read a configuration file, or, in the case of my Ant Task, you can use Ant’s build file. Another example is JDBC, where you write your program to access a database but not a specific database. You get a JDBC database driver based on a string, not the name of a particular class. This allows you (supposedly) the ability to add a JDBC driver, change a configuration file and your app now uses a different database. Too bad this doesn’t happen as easily in real life, but it is a lot better than the equivalent solution in… say, PHP. Decorator / Wrapper Take, for instance, the Decorator design pattern. The Gang of Four define this pattern as: Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extended functionality. But don’t let that terse statement throw you off. You’ve probably used this pattern before as this pattern comes in many flavors. Look at the way the Java I/O streams library is implemented: StreamTokenizer s =
new StreamTokenizer (
new BufferedReader (
new FileReader (file)));
Since just about every class in Often, we are used to creating a parent class and then adding features by subclassing the parent class and overriding one or more methods. This is not always ideal:
But the primary reason for creating a library based on this pattern is simply to limit the number of classes. In the case of the Another similar approach to this Decorator pattern is a “plugin” method, where a class is given additional functionality from another class. Like
passing a Of course, the classes must be architected with this sort of extension from the beginning. David Geary, in his article, Decorate Your Java Code, uses the Swing Table as an example of a class that can be extended by passing in a second class that implements an interface. The original Table class then calls a method in the passed in class. This is the approach I use in my Ant Task, where I can change how it parses and interprets input files by creating and specifying an “engine” through a simple Java class. Thought originally posted on Saturday, 25 September 2004
© 2004-2005, Howard Abrams • Except where otherwise noted, all original content is licensed under a Creative Commons License (see details). |
|||||||||||
|
||||||||||||