Iteratorパターン

Iteratorパターンとは

並んでいる要素に対し最初から最後まで「繰り返し処理」を行うパターンです。

Iteratorパターンの用途

Iteratorパターンは非常に汎用性が高いパターンです。
それはすなわち「いつでもどこでも使われている」ということであり、たとえばデータベースのレコードを最後までフェッチする仕組みとしてIteratorパターンが実装されていることもあるでしょう。
商品カテゴリを順次表示する仕組みとしてIteratorパターンを提供することもあるかも知れません。

そして、PHPにはすでにIteratorパターンの機構が用意されているので、そちらを利用してみましょう。

class Categories implements Iterator
{
  protected array $categories = [];

  function Categories(array $categories)
  {
    $this->categories = $categories;
  }

  function rewind()
  {
    reset($this->categories);
  }

  function current()
  {
    return current($this->categories);
  }

  function key()
  {
    return key($this->categories);
  }

  function next()
  {
    return next($this->categories);
  }

  function valid()
  {
    return false !== current($this->categories);
  }
}

$categories = new Categories(['CPU', 'メモリ', 'ハードディスク']);

foreach ($categories as $category) {
  echo $category . "\n";
}

ん?これって $categories そのものを配列にしてしまえばいいんじゃない?と思われるかも知れません。
そのとおりです。
PHPの配列とforeach構文が非常に協力なので、PHPにおいてはIteratorパターンの出る幕がないのです。

Iteratorパターン以前

昨今のプログラム言語では配列の操作が便利になっていたり、最初からIteratorパターンが導入されているので、
Iteratorを意識することは少ないかも知れません。
では、それらが実装されるまでの表記はどのようになっていたでしょうか?

    CategoryAggregate aggregate = new CategoryAggregate();
    aggregate.addCategory(new Category("CPU"));
    aggregate.addCategory(new Category("メモリ"));
    aggregate.addCategory(new Category("ハードディスク"));
    Iterator itr = aggregate.iterator();
    while (it.hasNext()) {
        Category category = (Category) itr.next();
        System.out.println(category.getName());
    }

冗長ですよね。
このような表記を避けるために、先人が実装を進めてくれていたわけです。