Forwarding Collectionsのクラスは、 java.io.inputStreamで使われているようなデコレーション(Decoration)パターンをコレクション系のクラスに使うときに便利なクラスです。 直接、Extendするより柔軟に使えますし。コレクション系のクラスを拡張するときは、まず使って行こうと思います。 (ArrayListをextendsしたら、LinkListには使えなくなる) またコードを直接見たほうが理解しやすい場合もあります。 例えば、FowrdingObject.java (下はコメントなどを除去) だけのクラスです。 ただコレクションのクラスをoverwriteしていないので、デコレーションの例としてはいま1つわかりにくかったですね。Listとか見てみてください。 public abstract class ForwardingObject { protected ForwardingObject() {} protected abstract Object delegate(); @Override public String toString() { return delegate().toString(); } } Forwardingの使用例ForwardingListを使った例ここでは、FowwardingListを拡張して、配列の指定のindexのアイテムを上下に移動できるようにしてみました。 結局自分で、すべてのメソッドoverwriteする手間を考えたらGoogle Collecions使うのが便利ですね。 このMovableListは、ボタン押したら、並び方が変わる時に使っています。 public static void main(String argv[]){ List<String> array=Lists.newArrayList("1","2","3","4"); MovableList<String> mo=new MovableList<String>(array); mo.moveUp(2); System.out.println(Joiner.on(',').join(mo)); array=Lists.newLinkedList(array); mo.moveDown(2); System.out.println(Joiner.on(',').join(mo)); } FowrardingMultisetを使った例Google Collections Library内部での使用例forwarding collectionsはGoogle CollectionsのBiMapやMultisetやMultimapの中で使われています。UnmodifiableMultisetやUnmotifiableMultimapの元になっています。 以下のように不要なメソッドを上書きすることで、修正不可を実現しています。 機能を加えるだけでなく機能を省くのにもForwardingは使えるのですね。 @Override public boolean add(E element) { throw new UnsupportedOperationException(); } @Override public boolean remove(Object element) { throw new UnsupportedOperationException(); } Forwardingを使った他の例 by Google Code Searchやはり、実例のコードをを見たほうがわかりやすいこともあります。 addした数を数えたり、遅延ロードしたりを実現しています。addと同時にリスナー追加などもしています。 ForwardingList ForwardingSet ForwardingMap
デコレーション(Decoration)パターンこのForwarding Collectionsの理解には、Decorationの理解が不可欠です。使った例としてはInputStreamがJavaでは有名です。 デザインパターンの1つであるデコレーションパターンについては、以下リンクを見てみることをお勧めします。 |
Java ライブラリー > Google Collections Library >