何番煎じか判りませんがお勉強メモを残します
「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