デザインパターン「Iterator」

# はじめに
<a href="http://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E5%86%8D%E5%88%A9%E7%94%A8%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF-%E3%82%AC%E3%83%B3%E3%83%9E/dp/4797311126" target="_blank">GoF</a>のデザインパターンがまとめられた<a href="http://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030/ref=sr_1_1?ie=UTF8&qid=1454743284&sr=8-1&keywords=java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80" target="_blank">Java言語で学ぶデザインパターン入門</a>で学んだことをまとめていきたいと思います。
参考書に沿ってJavaで説明していきますが、何か気になる箇所や改善点があれば気軽にコメントもらえると幸いです
[まとめ一覧はこちら](#design_pattern)

# Iteratorパターン
## Iteratorとは
単語自体は***繰り返す***、***反復する***などの意味を持ち、集約したオブジェクトを列挙する手段を提供するデザインパターンです。
次のような場合にIteratorパターンに準拠して実装するべきだと考えられます。

- アプリケーション固有なデータ、構造を持ったオブジェクトにアクセスをする場合
- 配列やコレクションなどの集合する要素にアクセスする場合(配列はforループで回せるが、リストなどのコレクションは難しかったりする)
- 集合の要素に順次にアクセスする必要がある場合

## Iteratorパターンのクラス図
<p align="center"><img width="550" alt="スクリーンショット 2016-02-06 23.08.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/62451/9eb14505-7b96-9c99-f472-ee3a26c106ec.png"></p>

- ConcreteAggregateクラスでConcreteIteratorクラス(要素にアクセスする役割)のインスタンス生成
- Iteratorの必要性については<a href="#last_content">後述</a>

## 具体例

- ConcreteAggregateクラス : [BookShelf(本棚)](#concrete_aggregate)
- BookShelfクラスは複数の[Bookクラス](#book)を持つ
- ConcreteIteratorクラス : [BookShelfIterator](#concrete_iterator)

今回のIteratorで用いる汎用メソッドはこの二つです
<dl>
 <dt>1. `next()`</dt>
 <dd>次の要素を返す(現在の要素を返し、次の位置に進める)</dd>
 <dt>2. `hasNext()`</dt>
 <dd>次の要素が存在するか調べ、真偽値を返す</dd>
</dl>
以下のようなIteratorのインスタンスが本棚の本を列挙していく例で説明していきます。

## <a id="main_class">Mainクラス</a>
```java:Main.java
public static void main(String[] args) {
		BookShelf bookShelf = new BookShelf(4);
		
		bookShelf.appendBook(new Book("Git Hub"));
		bookShelf.appendBook(new Book("Qiita"));
		bookShelf.appendBook(new Book("Java"));
		bookShelf.appendBook(new Book("Iterator pattern"));
		
		Iterator iterator = bookShelf.iterator();
		while(iterator.hasNext()) {
			Book book = (Book)iterator.next();
			System.out.println(book.getName());
		}
	}
```

## 抽象クラス
```java:Aggregate.java
public interface Aggregate {
	public abstract Iterator iterator();
}
```
```java:Iterator.java
public interface Iterator {
	public abstract boolean hasNext();
	public abstract Object next();
}
```
## 具象クラス

<a id="concrete_aggregate">本棚のクラス</a>

- Aggregateインタフェースを実装

```java:BookShelf.java
public class BookShelf implements Aggregate {
	private Book[] books;
	private int last = 0;
	
	public BookShelf(int maxsize) {
		this.books = new Book[maxsize];
	}
	
	public Book getBookAt(int index) {
		return books[index];
	}
	
	public void appendBook(Book book) {
		this.books[last] = book;
		last++;
	}
	
	public int getLength() {
		return last;
	}
	
	public Iterator iterator() {
		return new BookShelfIterator(this);
	}
}
```
<a id="book">本のクラス</a>

- 今回は名前を返すだけのクラス

```java:Book.java
public class Book {
	private String name;
	
	public Book(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
}
```
<a id="concrete_iterator">本棚の要素にアクセスするクラス</a>

- Iteratorインタフェースを実装

```java:BookShelfIterator.java
public class BookShelfIterator implements Iterator {
	private BookShelf bookShelf;
	private int index;
	
	public BookShelfIterator(BookShelf bookShelf) {
		this.bookShelf = bookShelf;
		this.index = 0;
	}
	
	public boolean hasNext() {
		if (index < bookShelf.getLength()) {
			return true;
		} else {
			return false;
		}
	}
	
	public Object next() {
		Book book = bookShelf.getBookAt(index);
		index++;
		return book;
	}
}
```

## 実行結果

```java
Git Hub
Qiita
Java
Iterator pattern
```

## <a id="last_content">追記</a>

<dl>
 <dt>・Iterator役を生成することで利用側はConcreteAggregate(BookShelf)の実装を意識せず要素にアクセスできる</dt>
 <dd>ループでBookShelfのメソッドは呼ばれていないので依存関係がない</dd><br>
 <dt>・様々な要素の列挙が可能</dt>
 <dd>最初(後)・全部の要素を返す、逆方向に探索、要素を指定してジャンプするなど</dd>
</dl>


試しにBookShelfの実装を変えてみましょう
Bookの配列ではなく`java.util.ArrayList`を用いてみます

```java:BookShelf.java
import java.util.ArrayList;

public class BookShelf implements Aggregate {
	private ArrayList books;
	
	public BookShelf(int initialize) {
		this.books = new ArrayList(initialize);
	}
	
	public Book getBookAt(int index) {
		return (Book)books.get(index);
	}
	
	public void appendBook(Book book) {
		books.add(book);
	}
	
	public int getLength() {
		return books.size();
	}
	
	public Iterator iterator() {
		return new BookShelfIterator(this);
	}
}
```

### 実行結果

[Mainクラス](#main_class)の実装は変えていませんが同じ結果が得られました。

```java
Git Hub
Qiita
Java
Iterator pattern
```


### サンプルコードについて

以下のレポジトリにソースコードをアップしてあります。

[shoheiyokoyama/design-pattern_java](https://github.com/shoheiyokoyama/design-pattern_java/tree/master/Iterator)

# <a id="design_pattern">デザインパターン</a>
- 生成に関するパターン
 - Abstract factory
 - Builder
 - <a href="http://qiita.com/shoheiyokoyama/items/d752834a6a2e208b90ca" target="_blank">Factory Method</a>
 - <a href="http://qiita.com/shoheiyokoyama/items/61826e158b3c4a259065" target="_blank">Prototype</a>
 - <a href="http://qiita.com/shoheiyokoyama/items/c16fd547a77773c0ccc1" target="_blank">Singleton</a>
- 構造に関するパターン
 - <a href="http://qiita.com/shoheiyokoyama/items/bd1c692db480b640c976" target="_blank">Adapter</a>
 - Bridge
 - Composite
 - Decorator
 - Facade
 - Flyweight
 - Proxy
- 振る舞いに関するパターン 
 - Chain of responsibility
 - Command
 - Interpreter
 - <a href="http://qiita.com/shoheiyokoyama/items/3f42d0057d9d5a861039" target="_blank">Iterator</a>
 - Mediator
 - Memento
 - <a href="http://qiita.com/shoheiyokoyama/items/d4b844ed29f84a80795b" target="_blank">Observer</a>
 - State
 - Strategy
 - <a href="http://qiita.com/shoheiyokoyama/items/c2ce16b4f492cd014d50" target="_blank">Template Method</a>
 - Visitor

# 参考文献
<a href="http://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030/ref=sr_1_1?ie=UTF8&qid=1454743284&sr=8-1&keywords=java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80" target="_blank">Java言語で学ぶデザインパターン入門</a>