Iterator Pattern

<font color="#00f">
userが操作できるのはhasNext()とnext()だけにし
Iteratorの実装クラスを隠ぺいすることで
userとIterator実装クラスとの依存性を解消する
</font>

このページでは
・Iteratorの構造確認
・Iteratorの隠蔽
・Iterator Patternとオブジェクト指向
について記載しています

[Design Pattarm MENU](https://qiita.com/old_cat/items/852d980bedb9100dd7e3)

##Iteratorの構造確認
以下のclass構成で確認します

|クラス|説明|
|----|---------|
|sam.class|配列とIterator()を持つ|
|Itarator.class|sam.classの配列要素を呼び出す|
|user(Main.class)|sam.classを使う|

＊user　他の開発者がこのパターンを利用する、という意味合いを含みます

samとIteratorクラスの基本構造は以下の感じです

```java:sam.class
class sam{
  int[] i= {0,1,2};
  Iterator iterate(){}
}
```

```java:Iterator.class
class Iterator{
  boolean hasNext(){}
  int next(){}
}
```

<br>
では実際に各クラスを作っていきます

```java:sam.class
class sam{
  int[] i={0,1,2};

  Iterator iterate(){           // Iteratorを返します
    return new Iterator(this.i); // Iterator.classにsamの配列を引数として渡します
  }
}
```

```java:Iterator.class
class Iterator{
  int[] i;                      // sam.classの配列を格納します　A
  int index=0;                  // 配列の要素を数える変数です    B

  Iterator(int[] i){this.i=i;}  // sam.classから配列を引き取り、Aに格納します

  boolean hasNext(){
    boolean b=false;
    if(index<i.length){b=true;} //　配列の要素数と B の値を比較して、次の要素があるか判定します
    else{return b;}
    return b;
  }

  int next(){
    int ans = i[index];         // 現在の要素をsam.classに戻します
    index++;
    return ans;
  }
}
```

```java:user(Main.class)
public static void main(String[] args){
  sam s1 = new sam();
  Iterator it = s1.iterate();
  while(it.hasNext()){
    System.out.println((int) it.next());}
}}
```

##Iteratorの隠蔽
以下のclass構成で確認します
*user は　Main.classとします

|クラス|説明|
|----|---------|
|Interface.interface|user(Main.class)は、Interfaceとuse.classを介して、sam.classの機能を使う|
|use.class|sam.classのインスタンスを発行する|
|sam.class|userが利用する機能を実装する（配列とIterator機能）|
|Iterator.interface|userとsamIterator.classを仲介|
|samIterator|sam.classの配列要素を呼び出す|

基本的なクラス構成は下記です

```java:Interface.interface
interface Interface{
  Iterator iterate();
}
```
```java:use.class
class use {
  Interface newInstance(){}
}
```
```java:sam.class
class sam implements Interface{
  int[] i={0,1,2};
  Iterator iterate(){}
}
```

[ Iterator側 ]

```java:Iterator.interface
interface Iterator{
  boolean hasNext();
  int     next();
}
```

```java:samIterator.class
class samIterator implements Iterator{
  samIterator(){}
  public  boolean hasNext(){}
  public  int next(){}
}
```

では各クラスを作ります

```java:Interface.interface
interface Interface{
  Iterator iterate();
}
```
```java:use.class
class use {
  public static Interface newInstance(){
         return new sam();}
}
```
```java:sam.class
class sam implements Interface{
  private int[] i={0,1,2};

  public  Iterator iterate(){
          return new samIterator(this.i);
  }
}
```
```java:Iterator.interface
interface Iterator{
  boolean hasNext();
  int     next();
}
```
```java:samIterator.class
class samIterator implements Iterator{
  private int i[];
  private int index=0;

  samIterator(int[] i){
          this.i=i;
  }

  public  boolean hasNext(){
          if(index<i.length){return true;}
          else{return false;}
  }

  public  int next(){
          int ans = i[index];
          index++;
          return ans;}
}
```
```java:user(Main.class)
public static void main(String[] args){
  Interface face = use.newInstance();
  Iterator  it   = face.iterate();
  while(it.hasNext()){
    System.out.println(it.next());
}
```
##Iterator Pattern とオブジェクト指向
userからはuse.classと２つのinterfaceを利用するだけです
各実装クラスはUnvisible、これで依存性を解消します

開発者がsam.classの配列内容を変更したり
条件によってはMapを使うよう分岐処理に変更しても
Iteratorが機能する限りuser側は何も変更する必要がありません