この記事は何
デザインパターンについて、Rubyでどのような使い方ができるかをまとめた記事です。
デザインパターン自体の解説は詳しく行いません。
Iteratorパターンとは
Iteratorパターンとは、集合体に対して順番にアクセスするためのインターフェースを提供し、その実装を容易にするデザインパターンです。
詳しくは以下の記事をご覧ください。
Rubyでのコード例
元々のJava等での実装に則って実装すると以下のような形になると思います。
ただ、Rubyではこのような実装を行うことはあまりないと思います。(詳しくは次の項で解説します)
class ItemListIterator
def initialize(item_list)
@item_list = item_list
@current_index = 0
end
def has_next?
@current_index < @item_list.length()
end
def next
return nil unless has_next?
item = @item_list.get_at(@current_index)
@current_index += 1
return item
end
end
class ItemList
def initialize()
@item_list = []
end
def get_at(index)
@item_list[index]
end
def add(item)
@item_list << item
end
def length()
@item_list.length
end
def iterator
ItemListIterator.new(self)
end
end
これらのクラスを用いて以下のようにイテレーターを実現できます。
Item = Struct.new(:a, :b)
item_list = ItemList.new()
item_list.add(Item.new(1, 2))
item_list.add(Item.new(2, 3))
item_list.add(Item.new(3, 4))
iterator = item_list.iterator()
while iterator.has_next? do
puts iterator.next()
end
実行結果
#<struct Item a=1, b=2>
#<struct Item a=2, b=3>
#<struct Item a=3, b=4>
どのような時に使えるか
前項の冒頭でも紹介した通り、RubyではIteratorパターンそのものを実装する機会はほとんどないと思います。
その理由はEnumerable
モジュールが提供されているためです。
Enumerable
モジュールを利用すると以下のように、簡単にイテレータの実装が可能です。
class ItemList
include Enumerable
def initialize()
@item_list = []
end
def add(item)
@item_list << item
end
def each(&block)
@item_list.each(&block)
end
end
Item = Struct.new(:a, :b)
item_list = ItemList.new()
item_list.add(Item.new(1, 2))
item_list.add(Item.new(2, 3))
item_list.add(Item.new(3, 4))
item_list.each do |item|
puts item
end
Enumerable
モジュールは以下の記事で詳しく解説されています。