(Заранее извините за мой русский)
Представьте, что вы разработчик статегичнои военной игры. Армия имеет сложную структуру: она состоит из героя и трех групп. Когда Король издает указ и ресурсы, чтобы полечить всех воинов (Герой также является воином) Вы хотите проитеруваты по всем солдатам и вызвать метод treat () на каждом инстанси. Как это можно сделать легко и без вникания в структуру армией?
Итератор это паттерн позволяющий доступатися к элементам любой коллекции без вникания в суть ее имплементации.
Таким образом в применении к нашей проблеме: Мы не хотим переживать структурой Армии — мы хотим чтобы SoldiersIterator пробежался по всем солдатам.
Красная линия на рисунке — это итератор (по крайней мере как я его себе представляю).

Код ниже показывает использование итератора. Как видим мы просто получили инстанс итератора SoldiersIterator. И простым циклом проходимося по всем солдатам армии. Это очень легко, что и является основной задачей итератора.
Армия состоит из одного героя и может содержать несколько групп, каждая из которых может содержать много солдат. Итак, как мы видим, сктуктура армии сложная и древовидная. Код ниже показывает создания Армии:
Герой (Hero) это класс унаслидуваний от солдата (Soldier) и основная разница такова, что он имеет более высокий уровень здоровья.
Поэтому, если мы можем двигаться по сложной коллекции так легко, где есть вся сложность?
Конечно, она скрыта инкапсулированные в конкретном классе итератора.
Потому что я себе поставил задачу подчеркнуть главная задача которую решает этот паттерн и сделать это таким образом, что можно будет все легко зрозмиты. Еще одной причиной является то, что вы можете прочитать тонны стандартных объяснений этого паттерна. Главной же разницей между моим объяснением и другими объяснениями является то, что стандартные более абстрагированные.
Например, я создавал нужный нам итератор следующим образом:
Но обычно создания итератора также инкапсулюеться под методом агрегата (как GetEnumerator в. NET). Мой код мог бы выглядеть так:
В мире. NET мы интерфейсы IEnumerable и IEnumerator , которые нам помогают в использовании этого паттерна.
В Java мы java.lang.Iterable вместо IEnumerable, что очевидно является более интуитивной названием. Я думаю что Microsoft просто хотели быть более оригинальными в этом вопросе:).
По этой ссылке мне понравились объяснения различий между этими двумя языками:
http://www.25hoursaday.com/CsharpVsJava.html
Моя табличка паттернов
Представьте, что вы разработчик статегичнои военной игры. Армия имеет сложную структуру: она состоит из героя и трех групп. Когда Король издает указ и ресурсы, чтобы полечить всех воинов (Герой также является воином) Вы хотите проитеруваты по всем солдатам и вызвать метод treat () на каждом инстанси. Как это можно сделать легко и без вникания в структуру армией?
ИТЕРАТОР
Итератор это паттерн позволяющий доступатися к элементам любой коллекции без вникания в суть ее имплементации.
Таким образом в применении к нашей проблеме: Мы не хотим переживать структурой Армии — мы хотим чтобы SoldiersIterator пробежался по всем солдатам.
Красная линия на рисунке — это итератор (по крайней мере как я его себе представляю).

Использование
Код ниже показывает использование итератора. Как видим мы просто получили инстанс итератора SoldiersIterator. И простым циклом проходимося по всем солдатам армии. Это очень легко, что и является основной задачей итератора.
SoldiersIterator iterator = new SoldiersIterator(earthArmy);
while(iterator.hasNext()){
Soldier currSoldier = iterator.next();
currSoldier.treat();
}
* This source code was highlighted with Source Code Highlighter.
Структура Армии
Армия состоит из одного героя и может содержать несколько групп, каждая из которых может содержать много солдат. Итак, как мы видим, сктуктура армии сложная и древовидная. Код ниже показывает создания Армии:
Army earthArmy = new Army();
Group groupA = new Group();
for(int i=1; i<4; ++i)
groupA.addNewSoldier(new Soldier("Alpha:" + i));
Group groupB = new Group();
for(int i=1; i<3; ++i)
groupB.addNewSoldier(new Soldier("Beta:" + i));
Group groupC = new Group();
for(int i=1; i<2; ++i)
groupC.addNewSoldier(new Soldier("Gamma:" + i));
earthArmy.ArmyHero = new Hero("Andriy Buday");
earthArmy.addArmyGroup(groupB);
earthArmy.addArmyGroup(groupA);
earthArmy.addArmyGroup(groupC);
* This source code was highlighted with Source Code Highlighter.
Герой (Hero) это класс унаслидуваний от солдата (Soldier) и основная разница такова, что он имеет более высокий уровень здоровья.
public class Soldier {
public String Name;
public int Health;
protected int maxHealthPoints = 100;
public Soldier(String name){
Name = name;
}
public void treat(){
Health = maxHealthPoints;
System.out.println(Name);
}
}
public class Hero extends Soldier {
protected int maxHealthPoints = 500;
public Hero(String name) {
super(name);
}
}
* This source code was highlighted with Source Code Highlighter.
SoldiersIterator
Поэтому, если мы можем двигаться по сложной коллекции так легко, где есть вся сложность?
Конечно, она скрыта инкапсулированные в конкретном классе итератора.
public class SoldiersIterator {
private Army _army;
boolean heroIsIterated;
int currentGroup;
int currentGroupSoldier;
public SoldiersIterator(Army army) {
_army = army;
heroIsIterated = false;
currentGroup = 0;
currentGroupSoldier = 0;
}
public boolean hasNext() {
if(!heroIsIterated) return true;
if(currentGroup < _army.ArmyGroups.size())return true;
if(currentGroup == _army.ArmyGroups.size()-1)
if(currentGroupSoldier < _army.ArmyGroups.get(currentGroup).Soldiers.size())return true;
return false;
}
public Soldier next() {
Soldier nextSoldier;
// we still not iterated all soldiers in current group
if (currentGroup < _army.ArmyGroups.size()) {
if (currentGroupSoldier < _army.ArmyGroups.get(currentGroup).Soldiers.size()) {
nextSoldier = _army.ArmyGroups.get(currentGroup).Soldiers.get(currentGroupSoldier);
currentGroupSoldier++;
}
// moving to next group
else {
currentGroup++;
currentGroupSoldier = 0;
return next();
}
}
// hero is the last who left the battlefield
else if (!heroIsIterated) {
heroIsIterated = true;
return _army.ArmyHero;
} else {
// THROW EXCEPTION HERE
throw new IllegalStateException("End of colletion");
//or set all counters to 0 and start again, but not recommended
}
return nextSoldier;
}
}
* This source code was highlighted with Source Code Highlighter.
Чем мой пример отличается от стандартного GoF?
Потому что я себе поставил задачу подчеркнуть главная задача которую решает этот паттерн и сделать это таким образом, что можно будет все легко зрозмиты. Еще одной причиной является то, что вы можете прочитать тонны стандартных объяснений этого паттерна. Главной же разницей между моим объяснением и другими объяснениями является то, что стандартные более абстрагированные.
Например, я создавал нужный нам итератор следующим образом:
SoldiersIterator iterator = new SoldiersIterator (earthArmy);
* This source code was highlighted with Source Code Highlighter.
Но обычно создания итератора также инкапсулюеться под методом агрегата (как GetEnumerator в. NET). Мой код мог бы выглядеть так:
IIterator iterator = AbstractArmy.GetSoldiersIterator ();
* This source code was highlighted with Source Code Highlighter.
В мире. NET мы интерфейсы IEnumerable и IEnumerator , которые нам помогают в использовании этого паттерна.
var list = new List <int> ();
//GetEnumerator is method of IEnumerator (Aggregate)
var enumerator = list.GetEnumerator ();
//MoveNext method of IEnumerable (Iterator)
enumerator.MoveNext ();
* This source code was highlighted with Source Code Highlighter.
В Java мы java.lang.Iterable вместо IEnumerable, что очевидно является более интуитивной названием. Я думаю что Microsoft просто хотели быть более оригинальными в этом вопросе:).
По этой ссылке мне понравились объяснения различий между этими двумя языками:
http://www.25hoursaday.com/CsharpVsJava.html
Моя табличка паттернов