第1章 Iterator - 増補改訂版Java言語で学ぶデザインパターン入門
というわけで、デザインパターンの復習。第1章のIteratorパターンから。
- Iteratorパターンを使うメリットは、集合体の実装と、集合体から個体を取り出す動作を分離できること。
集合体がどんなふうに実装されていても、集合体用のIteratorが正しいかぎりは、使う側が個体を取り出す動作を変えなくてよい、と書いてあります。便利。
- 集合体の実装と数え上げの実装は、密接に関連している。集合体の実装に変更が加われば、数え上げの実装も変更する必要がある。
数え上げを実装したクラスのnext()では、次の要素を取得して、インデックスを1進めます。next()は、内部で、集合体の実装クラスに記述された「指定したインデックスの要素を返す」メソッドを使っています。集合体の実装変更によって、「指定したインデックスの要素を返す」メソッドがシグネチャごと変わってしまうと、next()も変更することになりますよ、という話。
Iteratorパターンの実装は、java.util.Iteratorインタフェースに見ることができる。
複数のIteratorを併用する方法
サンプルプログラムのIterator実装は、集合体に対して、順方向に一度だけ走査します。では、異なる走査の仕方をするIteratorを後から併用したくなったら、どのように実現するとよいのか?
集合体の実装では、すでにAggregateインタフェースのiterator()をオーバライドしている。このiterator()は、順方向に走査するIteratorを作るためのものだ。となると、逆方向に走査するIteratorを作るメソッドを別に定義する必要がある。
ここで、Iterator (Java Platform SE 6)とListIterator (Java Platform SE 6)を見てみる。
逆方向に走査するメソッドは、Iteratorインタフェースでなく、Iteratorを拡張したListIteratorインタフェースにある。この方法を参考にすると、こうなる。まず、元のIteratorを拡張したListIteratorを作る。次に、ListIteratorに逆走査メソッドを追加する。最後に、逆走査メソッドを使いたいクラスで、IteratorでなくListIteratorを実装する。
元のIteratorインタフェースを肥大させないように気をつけよう(昔よくやってた…)。インタフェースに後からメソッドを追加するのは、じごくの入り口。
ジェネリックスを使う
練習問題の解答のサンプルコードでは、AllayListが生のままで使われている。
// (付属CDルート)/src/Iterator/A1/BookShelf.java から引用 private ArrayList books; public BookShelf(int initialsize) { this.books = new ArrayList(initialsize); } public Book getBookAt(int index) { return (Book)books.get(index); }
取り出し時にキャストしなくてよいように、ジェネリックスを使ってみる。
// 変更後 private ArrayList<Book> books; public BookShelf(int initialize) { this.books = new ArrayList<Book>(initialize); } public Book getBookAt(int index) { return books.get(index); }
for文でhasNextを使う
サンプルコードでは、hasNextの条件付き繰返しをwhile文で書いている。
// (付属CDルート)/src/Iterator/Sample/BookShelf.java から引用 Iterator it = bookShelf.iterator(); while (it.hasNext()) { Book book = (Book)it.next(); System.out.println(book.getName()); }
変数のスコープを最小にしよう、という理念にしたがって、この部分をfor文にしてみる。
// 変更後 for(Iterator it = bookShelf.iterator();it.hasNext();) { Book book = (Book)it.next(); System.out.println(book.getName()); }
なぜこうするのかについて、コードで説明しているページを見つけたので、メモ。
・http://www.sgnet.co.jp/java/chapter0101.html
第1章は、ここまで。