Die Rolle der Scanelemente in der richtigen Reihenfolge
package iterator;
public interface Iterator {
public abstract boolean hasNext();
public abstract Object next();
}
Die Rolle der Implementierung der Schnittstelle, die durch die Rolle des Iterators definiert wird
package iterator;
public class BookShelfIterator implements Iterator {
private BookShelf bookShelf;
private int index;
public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
}
public boolean hasNext() {
return index < bookShelf.getLength();
}
public Object next() {
Book book = bookShelf.getBookAt(index);
index++;
return book;
}
}
Eine Schnittstelle, die die Rolle des Iterators erstellt.
package iterator;
public interface Aggregate {
public abstract Iterator iterator();
}
Eine Rolle, die die durch die Aggregatrolle definierte Schnittstelle implementiert
package iterator;
import java.util.ArrayList;
import java.util.List;
public class BookShelf implements Aggregate {
private List<Book> books;
public BookShelf() {
this.books = new ArrayList<>();
}
public Book getBookAt(int index) {
return books.get(index);
}
public void appendBook(Book book) {
books.add(book);
}
public int getLength() {
return books.size();
}
public Iterator iterator() {
return new BookShelfIterator(this);
}
}
package iterator;
import java.util.ArrayList;
import java.util.List;
public class BookShelf implements Aggregate {
private List<Book> books;
public BookShelf() {
this.books = new ArrayList<>();
}
public Book getBookAt(int index) {
return books.get(index);
}
public void appendBook(Book book) {
books.add(book);
}
public int getLength() {
return books.size();
}
public Iterator iterator() {
return new BookShelfIterator(this);
}
}
package iterator;
public class Book {
private String name;
public Book(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
package iterator;
public class Main {
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf();
bookShelf.appendBook(new Book("Effective Java"));
bookShelf.appendBook(new Book("CODE COMPLETE"));
bookShelf.appendBook(new Book("Lesbarer Code"));
bookShelf.appendBook(new Book("Verbesserung des Legacy-Codes"));
Iterator it = bookShelf.iterator();
while (it.hasNext()) {
Book book = (Book)it.next();
System.out.println(book.getName());
}
}
}
Warum müssen wir eine Iteratorrolle außerhalb des Aggregats erstellen? Der Hauptgrund ist, dass es mit Iterator möglich ist, getrennt von der Implementierung zu zählen.
while (it.hasNext()) {
Book book = (Book)it.next();
System.out.println(book.getName());
}
Im obigen Code werden nur die Iterator-Methoden hasNext und next verwendet. Die in der BookShelf-Implementierung verwendeten Methoden wurden nicht aufgerufen. Diese Schleife hängt also nicht von der Implementierung von BookShelf ab.
Stellen Sie sich den Fall vor, in dem BookShelf die Verwaltung von Büchern mit List beendet und Änderungen an der Verwendung von Arrays vornimmt. Unabhängig davon, wie Sie BookShelf ändern, verfügt BookShelf über einen Iterator und Wenn Sie den richtigen Iterator zurückgeben (wenn er eine Instanz der Klasse zurückgibt, in der die Methoden hasNext und next korrekt implementiert sind), muss die obige Schleife überhaupt nicht geändert werden.
Personen, die nicht mit der Verwendung abstrakter Klassen und Schnittstellen vertraut sind, programmieren in der Regel die Rolle des konkreten Aggregats oder des konkreten Iterators anstelle der aggregierten Schnittstelle oder der Iterator-Schnittstelle (ich bin jetzt ...).
Wenn nur bestimmte Klassen verwendet werden, sind die Bindungen zwischen den Klassen stark und es wird schwierig sein, sie als Teile wiederzuverwenden.
Abstrakte Klassen und Schnittstellen werden eingeführt, um die Bindung zu schwächen und die Wiederverwendung als Klassenkomponente zu erleichtern.
Recommended Posts