Posted at

Iteratorパターン

More than 5 years have passed since last update.


概要

デザインパターンのIteratorパターンの練習用の実装とそれに関することをまとめてみたものです。


サンプル

本棚(BookShelfクラス)に本(Bookクラス)を格納し、Iteratorクラスを使い本棚に格納された本の情報を順番に表示する。


Aggregate.java

public interface Aggregate {

public Iterator orderIterator();
public Iterator reverseIterator();
}


Iterator.java

public interface Iterator {

public boolean hasNext();
public Object next();
}


BookShelf.java

public class BookShelf implements Aggregate {

private List<Book> _books = new ArrayList<Book>();

public void addBook(Book book) {
_books.add(book);
}

public Book getBookAt(int idx) throws IndexOutOfBoundsException {
return _books.get(idx);
}

public void removeBookAt(int idx) throws IndexOutOfBoundsException {
_books.remove(idx);
}

public int getNumberOfBooks() {
return _books.size();
}

@Override
public Iterator orderIterator() {
return new OrderIterator(this);
}

@Override
public Iterator reverseIterator() {
return new ReverseIterator(this);
}
}



Book.java

public class Book {

private int _bookId;
private String _bookTitle;

public Book(int bookId, String bookTitle) {
_bookId = bookId;
_bookTitle = bookTitle;
}

public int getId() {
return _bookId;
}

public String getTitle() {
return _bookTitle;
}
}



OrderIterator.java

public class OrderIterator implements Iterator {

private BookShelf _baseObj;
private int _index = 0;

public OrderIterator(BookShelf bookShelf) {
_baseObj = bookShelf;
}

@Override
public boolean hasNext() {
try {
_baseObj.getBookAt(_index);
return true;
} catch (IndexOutOfBoundsException ex) {
return false;
}
}

@Override
public Object next() {
Book book = _baseObj.getBookAt(_index);
_index++;
return book;
}
}



ReverseIterator.java

public class ReverseIterator implements Iterator {

private BookShelf _baseObj;
private int _index;

public ReverseIterator(BookShelf bookShelf) {
_baseObj = bookShelf;
_index = _baseObj.getNumberOfBooks() - 1;
}

@Override
public boolean hasNext() {
try {
_baseObj.getBookAt(_index);
return true;
} catch (IndexOutOfBoundsException ex) {
return false;
}
}

@Override
public Object next() {
Book book = _baseObj.getBookAt(_index);
_index--;
return book;
}
}


インタフェース Aggregateクラス, Iteratorクラス。

具体的なクラスとして BookShelf, Book, (順番表示用)OrderIterator, (逆順表示用)ReverIteratorクラスを準備。

そんで、メインクラスで実行します。


Main.java

public class Main {

public static void main(String args[]) {
BookShelf bookShelf = new BookShelf();

bookShelf.addBook(new Book(1, "English"));
bookShelf.addBook(new Book(2, "Math"));
bookShelf.addBook(new Book(3, "History"));
bookShelf.addBook(new Book(4, "Physics"));
bookShelf.addBook(new Book(5, "Programming"));
bookShelf.addBook(new Book(6, "Science"));

System.out.println("------- Order -------");
Iterator orderIt = bookShelf.orderIterator();
while (orderIt.hasNext()) {
Book book = (Book) orderIt.next();
System.out.println("id: "+book.getId()+" title: "+book.getTitle());
}

System.out.println("------- Reverse Order -------");
Iterator reverseIt = bookShelf.reverseIterator();
while (reverseIt.hasNext()) {
Book book = (Book) reverseIt.next();
System.out.println("id: "+book.getId()+" title: "+book.getTitle());
}
}
}



Result

------- Order -------

id: 1 title: English
id: 2 title: Math
id: 3 title: History
id: 4 title: Physics
id: 5 title: Programming
id: 6 title: Science
------- Reverse Order -------
id: 6 title: Science
id: 5 title: Programming
id: 4 title: Physics
id: 3 title: History
id: 2 title: Math
id: 1 title: English


まとめ

・数え上げのロジックの実装を切り離すことで、Iteratorを使って順番に表示している側は、数え上げのロジックに変更があっても修正する必要が無い。

・積極的に抽象クラスやインタフェースを使うことはクラス間の結合度に大きく関わる。

・様々な数え上げのIteratorを提供できる。今回は順番に、逆順に操作を行うIteratorを実装してみた。