Introduction
An Adapter normally wraps another object, so that it can be used in an interface it wasn't designed for, e.g., when you want to use
interface Node {
Node parent();
Iterable<Node> children();
}
together with
class TreeModel {
private Node root;
// example method (stupid)
Node grandparent(Node node) {
return node.parent().parent();
}
}
and you're given a class like
class File {
File getParent() {...}
File[] listFiles() {...}
}
you need to write some FileToNodeAdapter.
Unfortunately, it means that you need to wrap each single object and you also need both a way to get from FileToNodeAdapter to File (which is trivial, since it's embedded), but also from File to FileToNodeAdapter, which leads either to creating a new object each time or to using some Map, which must be either globally accessible or referenced in each FileToNodeAdapter.
The Pattern
Replace the interface Node by
interface NodeWorker<T> {
T parentOf(T node);
Iterable<T> childrenOf(T node);
}
and modify the TreeModel like
class TreeModel<T> {
private NodeWorker<T> nodeWorker;
private T root;
// example method (stupid)
T grandparent(T node) {
return nodeWorker.parentOf(nodeWorker.parentOf(node));
}
...
}
Does this pattern have a name?
Are there any disadvantages, besides the fact that it is little bit more verbose and only applicable when you are in charge of the TreeModel code?
FileToNodeAdaptertoFileand back - the issues you describe remind of double dispatch - did you consider Visitor pattern to handle these? – gnat Oct 10 '11 at 12:54