LoginSignup
8

More than 5 years have passed since last update.

【デザインパターン】 Iteratorパターン

Last updated at Posted at 2015-06-16

概要

コンテナオブジェクトと、その要素へのアクセス、走査のためのインターフェイスを独立に実装したパターン

以下の4種類のクラスからなる
1. Iteratorクラス(コンテナオブジェクトの要素にアクセス、走査するためのインターフェイスを定義)
2. ConcreteIteratorクラス(1.で定義したインターフェイスを実装する)
3. Aggregateクラス(1.を生成するためのインターフェイスを定義)
4. ConcreteAggregateクラス(3.で定義したインターフェイスに対して適切な2.のインターフェイスを生成して返す)

具体例と実装

エンタメサイトの一覧ソート機能を例にすると

上記1~4はそれぞれ
1. 作品イテレータークラス
2. 新着順クラス
3. 作品一覧クラス
4. 映画一覧クラス

が対応する。
コードの詳細は以下

iterator.rb
class Iterator
  def initialize(aggregate)
    @aggregate = aggregate
    @index = 0
  end

  def has_next?
  end

  def next_item
  end
end
recent_iterator.rb
class RecentIterator < Iterator
  def initialize(aggregate)
    @aggregate = aggregate.sort do |(_k1, v1), (_k2, v2)|
      v1[:published_at] <=> v2[:published_at]
    end
  @index = 0
  end

  def has_next?
    @index < @aggregate.size
  end

  def next_item
    @index = @index + 1
    item = self.has_next? ? @aggregate.get_by_index(@index) : nil
  end
end
aggregate.rb
class Aggregate
  def initialize
    @works = []
  end

  def get_by_index(index)
  end

  def size
  end
end
MovieAggregate.rb
class MovieAggregate < Aggregate
  def initialize
    @works = []
  end

  def add_work(work)
    @works << work
  end

  def get_by_index(index)
    @works[index]
  end

  def size
    @works.size
  end
end
client.rb
movie_list = MovieAggregate.new
# 映画作品を追加していく
movie_list.add_work(...)
...
iterator = RecentIterator(movie_list)
while iterator.has_next?
  work = iterator.next_item
  puts work.title
end 

メリット

  • コンテナオブジェクトと走査のインターフェイスが独立しているため、コンテナの内部表現を公開せずに要素へのアクセスを提供出来る
  • あるコンテナオブジェクトに対して複数の走査をサポートできる
  • 異なるコンテナに対して、同一のインターファイスで要素にアクセス出来る

まとめ

コンテナの内部表現を隠蔽して要素へのアクセスを提供するパターン
あるコンテナの要素への複数のアクセス方法が必要な場合、または複数のコンテナの要素に対してアクセスする共通のインターファイスが必要な場合に用いる

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8