Sunteți pe pagina 1din 13

ITERATOR DESIGN

PATTERN
JAVA
DEFINIȚIE:
➤ Potrivit GoF, intenția modelului iterator de design este:

➤ Oferă o modalitate de a accesa elementele unui obiect agregat fără


a-și expune reprezentarea de bază.

➤ Modelul Iterator nu este doar despre parcurgerea printr-o colecție,


putem crea diferite tipuri de iteratori pe baza cerințelor noastre.

➤ Modelul de design Iterator ascunde implementarea reală de


parcurgere prin programele de colectare și client, folosind doar
metode iterator.
UNDE SE FOLOSEȘTE?
➤ Modelul Iterator (Iteraror Pattern) este folosit pentru a oferi
un mod standard de a parcurge printr-un grup de obiecte.
Modelul Iterator este folosit pe scară largă în cadrul Java
Collection Framework*. Interfața Iterator oferă metode pentru
parcurgerea printr-o colecție.
➤ *O colecție este un obiect care reprezintă un grup de obiecte
(cum ar fi clasa clasică Vector). Un cadru de colecții
( Collections Framework) este o arhitectură unificată pentru
reprezentarea și manipularea colecțiilor, permițând
manipularea colecțiilor independent de detaliile
implementării.
EXEMPLU DE ITERAROR PATTERN (MODEL ITERATOR):
➤ Să înțelegem modelul iterator cu un exemplu simplu. Să presupunem
că avem o listă de canale radio și programul client dorește să treacă
prin ele unul câte unul sau pe baza tipului de canal. De exemplu, unele
programe client sunt interesate numai de canalele de limba engleză și
dorește să le proceseze numai pe acestea, nu dorește să proceseze alte
tipuri de canale.

➤ Așadar, putem oferi clientului o colecție de canale (ChannelCollection)


și le permitem să scrie logica pentru a parcurge canalele și a decide
dacă să le proceseze. Dar această soluție are o mulțime de probleme,
cum ar clientul trebuie să vină cu logica pentru parcurgere. Nu ne
putem asigura că logica clientului este corectă. Mai mult, dacă numărul
clientului crește, atunci va fi foarte greu de menținut.
EXEMPLU DE ITERAROR PATTERN (MODEL ITERATOR):
➤ Aici putem folosi modelul Iterator și putem oferi iterație pe
baza tipului de canal. Ar trebui să ne asigurăm că programul
client poate accesa lista de canale numai prin iterator.
➤ Prima parte a implementării este definirea contractului (interfața expusă) pentru
interfețele noastre de colecție și iterator.

ChannelTypeEnum.java

package com.journaldev.design.iterator;
public enum ChannelTypeEnum {
ENGLISH, HINDI, FRENCH, ALL;
}

➤-ChannelTypeEnum este java enum ( creează câmpuri cu constante fixe) care definește
toate tipurile diferite de canale.
➤ A doua parte a implementării constă în crearea clasei Channel, care primește ca parametrii
frecvența și tipul canalului.

Channel.java

package com.journaldev.design.iterator;
public class Channel {
private double frequency;
private ChannelTypeEnum TYPE;

public Channel(double freq, ChannelTypeEnum type){


this.frequency=freq;
this.TYPE=type;
}
public double getFrequency() {
return frequency;
}
public ChannelTypeEnum getTYPE() {
return TYPE;
}

@Override
public String toString(){
return "Frequency="+this.frequency+", Type="+this.TYPE;
}

}
➤ Interfața ChannelCollection definește contractul pentru implementarea clasei noastre
de colecție. Observați că există metode de adăugare și eliminare a unui canal, dar nu
există nicio metodă care să returneze lista canalelor. ChannelCollection are o metodă
care returnează iteratorul pentru parcurgere.

ChannelCollection.java

package com.journaldev.design.iterator;

public interface ChannelCollection {

public void addChannel(Channel c);

public void removeChannel(Channel c);

public ChannelIterator iterator(ChannelTypeEnum type);

}
➤ Interfața ChannelIterator care returnează lista canalelor.

ChannelIterator.java

package com.journaldev.design.iterator;

public interface ChannelIterator {

public boolean hasNext();

public Channel next();


}
➤ Acum, interfața de bază și clasele de bază sunt gata, să continuăm cu implementarea clasei de colectare și a iteratorului.

ChannelCollectionImpl.java
@Override
public ChannelIterator iterator(ChannelTypeEnum type) {
package com.journaldev.design.iterator; return new ChannelIteratorImpl(type, this.channelsList);
}
import java.util.ArrayList;
import java.util.List; private class ChannelIteratorImpl implements ChannelIterator {

private ChannelTypeEnum type;


public class ChannelCollectionImpl implements ChannelCollection { private List<Channel> channels;
private int position;
private List<Channel> channelsList;
public ChannelIteratorImpl(ChannelTypeEnum ty,
List<Channel> channelsList) {
public ChannelCollectionImpl() {
this.type = ty;
channelsList = new ArrayList<>(); this.channels = channelsList;
} }

public void addChannel(Channel c) { @Override


public boolean hasNext() {
this.channelsList.add(c); while (position < channels.size()) {
} Channel c = channels.get(position);
if (c.getTYPE().equals(type) ||
public void removeChannel(Channel c) { type.equals(ChannelTypeEnum.ALL)) {
this.channelsList.remove(c); return true;
} else
} position++;
}
return false;
} }

@Override
public Channel next() {
Channel c = channels.get(position);
position++;
return c;
}

➤ Observație: implementarea de clasă interioară a interfeței iterator, astfel încât implementarea să nu poată fi
utilizată de nici o altă colecție. Aceeași abordare este urmată și de clasele de colecție toate au o implementare
internă de clasă a interfeței Iterator.
➤ Acum vom scrie un simplu program de testare a modelului iterator pentru a
folosi colecția și iteratorul pentru a parcurge colecția de canale.
IteratorPatternTest.java

package com.journaldev.design.iterator;

public class IteratorPatternTest {

public static void main(String[] args) {


ChannelCollection channels = populateChannels();
ChannelIterator baseIterator = channels.iterator(ChannelTypeEnum.ALL);
while (baseIterator.hasNext()) {
Channel c = baseIterator.next();
System.out.println(c.toString());
}
System.out.println("******");
// Channel Type Iterator
ChannelIterator englishIterator = channels.iterator(ChannelTypeEnum.ENGLISH);
while (englishIterator.hasNext()) {
Channel c = englishIterator.next();
System.out.println(c.toString());
}
}

private static ChannelCollection populateChannels() {


ChannelCollection channels = new ChannelCollectionImpl();
channels.addChannel(new Channel(98.5, ChannelTypeEnum.ENGLISH));
channels.addChannel(new Channel(99.5, ChannelTypeEnum.HINDI));
channels.addChannel(new Channel(100.5, ChannelTypeEnum.FRENCH));
channels.addChannel(new Channel(101.5, ChannelTypeEnum.ENGLISH));
channels.addChannel(new Channel(102.5, ChannelTypeEnum.HINDI));
channels.addChannel(new Channel(103.5, ChannelTypeEnum.FRENCH));
channels.addChannel(new Channel(104.5, ChannelTypeEnum.ENGLISH));
channels.addChannel(new Channel(105.5, ChannelTypeEnum.HINDI));
channels.addChannel(new Channel(106.5, ChannelTypeEnum.FRENCH));
return channels;
}

}
OUTPUT:
Frequency=98.5, Type=ENGLISH
Frequency=99.5, Type=HINDI
Frequency=100.5, Type=FRENCH
Frequency=101.5, Type=ENGLISH
Frequency=102.5, Type=HINDI
Frequency=103.5, Type=FRENCH
Frequency=104.5, Type=ENGLISH
Frequency=105.5, Type=HINDI
Frequency=106.5, Type=FRENCH
******
Frequency=98.5, Type=ENGLISH
Frequency=101.5, Type=ENGLISH
Frequency=104.5, Type=ENGLISH
CONCLUZII DESPRE ITERATOR PATTERN (MODEL
➤ Modelul Iterator este util atunci când se dorește o modalitate
standard de a repeta o colecție și de a ascunde logica de
implementare din programul client.
➤ Logica pentru iterație este încorporată în colecția însăși și
ajută programul clientului să se repete cu ușurință peste ele.