IteratorパターンをJavaとJavaScriptのコードを比較して理解する

#はじめに
詳しいことや他のパターンは**[デザインパターンをJavaScriptとJavaでの実装を比較して理解する](http://qiita.com/Kurowasi/items/106ebd0f553d8a2f95bb)**に書いて行きます。
JavaScriptの例はJavaのを見て書きました。
クラス型・プロトタイプ型、型付の強弱、アクセス修飾子など特徴の違いなどは活かしていません。(必要のないgetterなどもあります)
ご了承ください。

#Iteratorパターン
何かがたくさん集まっているときに、それを順番に指し示していき、全体をスキャンしていく処理を行うためのもの
iterateという英単語は何かを**繰り返す**という意味です。日本語では**反復子**と呼ばれることがある

##Javaでの実装例
本棚に数冊の本があり、その本棚ごとの本の冊数を数えるプログラム

###クラス図
![Iterator.png](https://qiita-image-store.s3.amazonaws.com/0/130026/2d39acc2-fc7f-adbe-2707-5f2a170d7873.png)



###コード
```Main.java
public class Main {
    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf(4);
        bookShelf.appendBook(new Book("Around the World in 80 Days"));
        bookShelf.appendBook(new Book("Bible"));
        bookShelf.appendBook(new Book("Chinderella"));
        bookShelf.appendBook(new Book("Dabby-Long-Legs"));
        Iterator it = bookShelf.iterator();
        while (it.hasNext()) {
            Book book = (Book)it.next();
            System.out.println(book.getName());
        }        
    }
}
```

```Aggregate.java
public interface Aggregate {
    public abstract Iterator iterator();
}
```

```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);
    }
}
```

```Book.java
public class Book {
    private String name;

    public Book(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}
```

```Iterator.java
public interface Iterator {
    public abstract boolean hasNext();
    public abstract Object next();    
}
```

```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;
    }
}
```

##JavaScriptの例
###コード
```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Iterator</title>
</head>
<body>
    <script src="Main.js"></script>
    <script src="Interface.js"></script>
    <script src="Aggregate.js"></script>
    <script src="BookShelf.js"></script>
    <script src="Book.js"></script>
    <script src="iterator.js"></script>
    <script src="BookShelfIterator.js"></script>
</body>
</html>
```

```Main.js
MAIN = {};
MAIN.init = function() {
    var bookShelf = new BookShelf();
    bookShelf.appendBook(new Book("Around the World in 80 Days"));
    bookShelf.appendBook(new Book("Bible"));
    bookShelf.appendBook(new Book("Chinderella"));
    bookShelf.appendBook(new Book("Dabby-Long=legs"));
    var it = bookShelf.iterator();
    while (it.hasNext()) {
        var book = it.next();
        console.log(book.name);
    }
};

window.addEventListener("load", MAIN.init);
```

```Interface.js
/**
 * @namespace INTERFACE
 */
INTERFACE = {};

/**
 * 同じプロパティを持っているか判定
 * @static
 * @method implements
 */
INTERFACE.implements = function(child, Pr) {
    var parent = new Pr();
    for (var p in parent) {
        if (!(p in child)) {
            console.error(child.constructor.name + "クラス(関数)に" + p + "メソッドが宣言されていません。");
        }
    }
};
```

```Aggregate.js
var Aggregate = function() {};
Aggregate.prototype.iterator = function() {};
```

```BookShelf.js
var BookShelf = function() {
    this.books = [];
    this.last = 0;

    INTERFACE.implements(this, Aggregate);
};

BookShelf.prototype = {
    constructor: BookShelf,

    getBookAt: function(index) {
        return this.books[index];
    },
    appendBook: function(book) {
        this.books[this.last] = book;
        this.last += 1;
    },
    getLength: function() {
        return this.last;
    },
    iterator: function() {
        return new BookShelfIterator(this);
    }
};
```

```Book.js
var Book = function(name) {
    this.name = name;
};

Book.prototype.getName = function() {
    return this.name;
};
```

```Iterator.js
var Iterator = function() {};
Iterator.prototype = {
    constructor: Iterator,

    hasNext: function() {},
    next: function() {}
};
```

```BookShelfIterator.js
var BookShelfIterator = function(bookShelf) {
    this.bookShelf = bookShelf;
    this.index = 0;

    INTERFACE.implements(this, Iterator);
};

BookShelfIterator.prototype = {
    constructor: BookShelfIterator,

    hasNext: function() {
        if (this.index < this.bookShelf.getLength()) {
            return true;
        } else {
            return false;
        }
    },
    next: function() {
        var book = this.bookShelf.getBookAt(this.index);
        this.index += 1;
        return book;
    }
}
```



##ある本に書いてあったJavaScriptでのIteratorパターン
Iteratorパターンは振る舞いなので、hasNext()とnext()があればいいってことなんですかね？
自分は再利用性が出来ない感じがするのでちょっと。。。って感じです
参考までに

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Iterator</title>
</head>
<body>
    <script src="Main.js"></script>
</body>
</html>
```

```Main.js
MAIN = {};

MAIN.init = function() {
    while(egg.hasNext()) {
        console.log(egg.next());
    }
};

var egg = (function() {
    var index = 0,
        data = [1, 2, 3, 4, 5],
        length = data.length;

    return {
        next: function() {
            var element;
            if (!this.hasNext()) {
                return null;
            }
            element = data[index];
            index = index + 1;
            return element;
        },

        hasNext: function() {
            return index < length;
        }
    };
}());

window.addEventListener("load", MAIN.init);
```
##Iteratorパターンの登場人物
###**Iterator(反覆子)の役**
要素を順番にスキャンしていくインタフェースを定める役
サンプルプログラム⇒Iterator(interface)
###**ConcreateIterator(具体的な反復子)の役**
Iterator役が定めたインタフェースを実際に実装する役
サンプルプログラム⇒BookShelfIterator(class)
###**Aggregate(集合体)の役**
Iterator役を作り出すインターフェースを定める役
サンプルプログラム⇒Aggregate(interface)
###**ConcreateAggregate(具体的な集合体)の役**
Aggregate役が定めたインタフェースを実際に実装する役
サンプルプログラム⇒BookShelf(class)

##Iteratorパターンのクラス図
![クラス図2.png](https://qiita-image-store.s3.amazonaws.com/0/130026/38e1af0a-69cf-b688-022a-43bc5e609011.png)


##Iteratorパターンの必要性
Iteratorパターンを使わなくても、for文などで回せばいいと思える
Iteratorを使う大きな理由は、Iteratorを使うことで、実装とは切り離して、数え上げを行うことが出来るからである

##イテレータの種類
今回の例では順方向に一度だけスキャンする単純なものだが、他にもある

+ 最後尾から開始して逆方向に進む
+ 順方向にも逆方向にも行く(next, previousメソッドの両方を持つ)
+ 番号を指定して、そこから始める
+ etc...

#関連しているパターン
+ Visitorパターン
+ [Compositeパターン](http://qiita.com/Kurowasi/items/b0123d20e052cb0bff44)
+ Factory Methodパターン



#参考
[増補改訂版Java言語で学ぶデザインパターン入門](https://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)
[JavaScriptパターン――優れたアプリケーションのための作法](https://www.oreilly.co.jp/books/9784873114880/)