LoginSignup
1
0

More than 5 years have passed since last update.

「HeadFirstデザインパターン」と「Rubyによるデザインパターン」を読んで Iterator パターン

Last updated at Posted at 2018-07-18

何番煎じか判りませんがお勉強メモを残します

HeadFirstデザインパターン」第2章
Rubyによるデザインパターン」第5章

Iterator パターン

「HeadFirstデザインパターン」でのJavaコードは(だいたい)こんな感じ

異なるCorrection 例えば

  • ArrayList
  • "配列"

に反復処理を行いたい場合、

ArrayList hogeArrayList = getHogeArrayList();

for (int i = 0, s = hogeArrayList.size(); i < s; i++) {
  Hoge hoge = (Hoge)hogeArrayList.get(i);
  // hoge への処理
}
Hoge[] hoges = getHogeArray();

for (int i = 0, l = hoges.length; i < l; i++) {
  Hoge hoge = hoges[i];
  // hoge への処理
}

何か微妙に違う・・!
反復処理を統一したい! collectionへの反復処理のカプセル化、それが

Iterator パターン

public interface Iterator {
  boolean hasNext();
  Object next();
}
public class HogeArrayListIterator implements Iterator {
  ArrayList<Hoge> hoges;
  int position = 0;

  public HogeArrayListIterator(ArrayList<Hoge> hoges) {
    this.hoges = hoges;
  }

  public Hoge next() {
    Hoge hoge = hoges.get(position);
    position++;
    return hoge;
  }

  public boolean hasNext() {
    if (position >= hoges.size()) {
      return false;
    }
    else {
      return true;
    }
  }
}

public class HogeArrayIterator implements Iterator {
  Hoge[] hoges;
  int position = 0;

  public HogeIterator(Hoge[] hoges) {
    this.hoges = hoges;
  }

  public Object next() {
    Hoge hoge = hoges[position];
    position++;
    return hoge;
  }

  public boolean nesNext() {
    if (position >= hoges.length) {
      return false;
    }
    else {
      return true;
    }
  }
}

つかいかた

ArrayList hogeArrayList = getHogeArrayList();
Hoge[]    hoges         = getHogeArray();

Iterator hogeArrayListIterator = new HogeArrayListIterator(hogeArrayList);
Iterator hogeArrayIterator     = new HogeArrayIterator(hoges);

while (hogeArrayListIterator.hasNext()) {
  Hoge hoge = (Hoge)hogeArrayListIterator.next()
  // hoge への処理
}

while (hogeArrayIterator.hasNext()) {
  Hoge hoge = (Hoge)hogeArrayIterator.next()
  // hoge への処理
}

つまり、どういうこと?

内部のcollectionを公開することなく、各アイテムに順次アクセスする方法を提供する

どうしてこんなことをするの?

「HeadFirstデザインパターン」では、ArrayListと配列で内部にcollectionを保持している2つのオブジェクトにおいて、
両方ともcollectionの持ち方を変えずに同じように扱いたい、というような例が挙げられていた

Rubyではどうなるんや?

class ArrayIterator
  def initialize(array)
    @array = array
    @index = 0
  end

  def has_next?
    @index < @array.length
  end

  def next_item
    value = @array[@index]
    @index += 1
    value
  end
end
hoges = [1, 2, 3, 4]

while hoges.has_next?
  p hoges.next_item
end
# =>
# 1
# 2
# 3
# 4

ていうか、rubyでは99%こんな事はしない

eachにブロックを渡すだけでいいのだから

hoges = [1, 2, 3, 4]

hoges.each do |hoge|
  p hoge
end
# =>
# 1
# 2
# 3
# 4
1
0
0

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
1
0