Iterator-Pattern
Robert R.
- programmiertechnik
Hallo,
also ich kann das Iterator Pattern ohne Probleme anwenden, versuch jetzt aber das UML-Diagramm zu verstehen da ich es für eine Klausur brauche.
http://de.wikipedia.org/wiki/Iterator_(Entwurfsmuster)
Klient
Aggregat
Konkretes Aggregat
Iterator
Konkreter Iterator
Elemement
echo $begrüßung;
http://de.wikipedia.org/wiki/Iterator_(Entwurfsmuster)
Klient
- die verwendete Methode, also die Methode in der ich den Iterator benutze, oder?
Nach meinem Verständnis ist das der Anwender, was wohl eher ein for/foreach ist als eine Methode, die noch jede Menge anderen Code enthalten kann.
Aggregat
- Abstrakter Datentyp - ich glaube in Java z. B. List
Das ist die Definition einer Schnittstelle, um einen Iterator zu bekommen. Also wie beim Iterator-Kästchen der rechten Seite nur ein Interface.
Konkretes Aggregat
- z. B. ArrayList oder?
Das ist der Teil, der den eigentlichen Iterator liefert, also die Implementation vom Aggregat-Interface. Welche konkrete Datenhaltung dahinter steht, also woher die Daten kommen und wieviel davon, ist unerheblich. Das kann intern eine ArrayList oder eine Datenbankabfrage oder sonstwas sein, für den Klienten spielt das keine Rolle. Dieses Implementierungsdetail bleibt ihm verborgen.
Iterator
- Interface dass lediglich Methoden festlegt, so richtig?
Ja, siehe Aggregat.
Konkreter Iterator
- Implementiertes Interface, so richtig?
Ja, das ist der Teil, der das jeweils aktuelle Element auf Anforderung hin liefert. Und gemäß Weiter() und Zurueck() seinen internen Merker auf andere Elemente setzt.
Elemement
- Einfach ein Objekt von vielen aus der Liste z. B. String, Person, Kunde...
Oder was auch immer. Ein Iterator kann beispielsweise auch einfach nur eine Zahl aus einem Bereich von m bis n liefern. Da braucht es keine Datenhaltung, der konkrete Iterator muss sich nur die aktuelle Zahl merken und bei Weiter() und Zurueck() inkrementieren oder dekrementieren. Ein Iterator könnte auch Zufallswerte zurückliefern, dann müsste er sich weder was merken noch braucht er eine Datenhaltung. Sein Ende findet er dann eben auch per Zufall. Inwieweit so ein "Zufallsiterator" außer zu Testzwecken sinnvoll ist, sei mal dahingestellt.
echo "$verabschiedung $name";
Danke dedlfix,
was ich noch nicht genaz verstehe, wo der konkret Iterator implementiert wird. Wenn ich nun ein konkretes Aggregat erstelle, muss ich dann 2 Klassen programmieren?
VG
echo $begrüßung;
Für C++ und Java kann ich nicht sprechen. Ich schweife mal kurz zu Python ab.
Um einen Iterator in Python zu implementieren ist es ausreichend, wenn ein Objekt eine next()-Methode hat[*][**]. Das reicht schon aus, um iterieren zu können und entspricht dem konkreten Iterator. Interfaces gibt es unter Python nicht. Ein Iterator-Lieferant in Form eines konkreten Aggregats kann mit der Methode __iter__() implementiert werden.
Ein Iterator allein läuft einfach nur durch eine Datenmenge. Normalerweise hat er keinen Mechanismus, um für eine weitere Iteration zurückgesetzt zu werden oder andere initiale Handlungen mit der Datenmenge anzustellen. Das muss der Aggregator machen, der quasi eine Art Konstruktor für einen Iterator darstellt.
was ich noch nicht genaz verstehe, wo der konkret Iterator implementiert wird. Wenn ich nun ein konkretes Aggregat erstelle, muss ich dann 2 Klassen programmieren?
Ein Interface, sofern es benötigt wird, muss nach den Gegebenheiten der jeweiligen Programmiersprache erstellt werden. In den meisten Fällen wird das wohl ein separates Gebilde sein. Das Interface ist ja nur eine nebensächliche Formsache. Im Folgenden meine ich immer nur eine konkrete Implementation.
Der Iterator kann für einfache[***] Fälle bereits in der Datenverwaltungs- bzw. -beschaffungsklasse implementiert werden, über die dann auch iteriert wird. Wenn du ein Aggregat benötigst, ist es günstig, dieses in der zu iterierenden Datenmenge zu implementieren und den Iterator in eine eigene Klasse zu tun, weil du dir für jede Iteration einzeln merken musst, wo der Aktuelles-Element-Zeiger grad ist oder vielleicht um eine Kopie der Daten(teil)menge zu speichern. Für jede Iteration erzeugt das Aggregat dann eine eigens erstellte Instanz des Iterators. Es ist aber auch möglich, Aggregat und Iterator in die Datenklasse zu packen. Die Aggregat-Methode nimmt beim Start einer Iteration die Initialisierung vor und gibt dann das Objekt für das sie aufgerufen wurde (this, self) zurück, weil dieses ja auch eine Iterator-Implementation ist. Du hast dann nur das Problem, dass nur ein Objekt existiert, das alle (vielleicht gleichzeitig laufenden) Iterationen so verwalten muss, dass sich diese nicht ins Gehege kommen.
- das Aggregat selbst
- den zugehörigen Iterator
oder? Da in C++ Iteratoren Pointer sind kann man in C++ diese als innere Klassen implementieren. In Java müssten diese als separate Dateien, also als separate Klassen implementiert werden. Ist das so richtig?
Da ich C++ und Java nicht bedienen kann muss ich dir eine konkrete Antwort schuldig bleiben. Außer Python kenne ich nur Iterator und IteratorAggregate von PHPs SPL. Dasjenige Objekt, das in der foreach-Schleife als das zu iterierende angegeben werden soll, muss entweder mittels IteratorAggregate-Implementation eine Iterator-Implementation zurückliefern oder selbst eine Iterator-Implementation enthalten.
[*] Zumindest etwas, das sich wie eine Methode anfühlt. Man kann ja auch eine Objektinstanz callable machen.
[**] Diese Methode wird beim Iterieren solange aufgerufen, bis sie eine StopIteration-Exception wirft. Sie ist also Weiter(), IstFertig() und AktuellesElement() in Personalunion.
[***] auch im Sinne von nur einmal zu durchlaufen zu verstehen.
echo "$verabschiedung $name";