Design Pattern--Iterator Pattern

Direct Code: Bookshelf Small Example

public class Book {
    private String name;
    public Book(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}
public interface Iterator {
    boolean hasNext();
    Book next();
}
public interface Aggregate {
    Iterator iterator();
}
public class BookShelf implements Aggregate{
    private List<Book> bookShelf;
    private int size;
    public BookShelf(int size) {
        bookShelf = Lists.newArrayListWithCapacity(size);
    }
    public Book getBook(int index) {
        return bookShelf.get(index);
    }
    public void addBook(Book book) {
        bookShelf.add(book);
        size++;
    }
    public int getSize() {
        return size;
    }

    @Override
    public Iterator iterator() {
        return new BookShelfIterator(this);
    }
}
public class BookShelfIterator implements Iterator {
    private BookShelf mBookShelf;
    private int index;
    public BookShelfIterator(BookShelf bookShelf) {
        mBookShelf =bookShelf;
        index = 0;
    }

    @Override
    public boolean hasNext() {
        if (index < mBookShelf.getSize()) {
            return true;
        }else {
            return false;
        }
    }

    @Override
    public Book next() {
        Book a = mBookShelf.getBook(index);
        index++;
        return a;
    }
}
public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf(4);
        bookShelf.addBook(new Book("a"));
        bookShelf.addBook(new Book("b"));
        bookShelf.addBook(new Book("c"));
        Iterator it = bookShelf.iterator();
        while (it.hasNext()) {
            System.out.println(it.next().getName());
        }
    }
The iterator pattern is a very frequently used design pattern. By introducing an iterator, the data traversal function can be separated from the aggregate object. The aggregate object is only responsible for storing data, and traversing data is completed by the iterator. Since the class libraries of many programming languages ​​have already implemented the iterator pattern, in actual development, we only need to directly use the iterators that have been defined in languages ​​such as Java and C# . Iterators have become the basis for us to operate aggregate objects. one of the tools.

 

       1.  Main advantages

       The main advantages of the iterator pattern are as follows:

       (1)  It supports traversing an aggregate object in different ways, and multiple traversal methods can be defined on the same aggregate object. In the iterator mode, we only need to replace the original iterator with a different iterator to change the traversal algorithm. We can also define a subclass of iterator to support the new traversal method.

       (2)  Iterators simplify aggregation classes. Due to the introduction of iterators, there is no need to provide methods such as data traversal in the original aggregate object, which simplifies the design of aggregate classes.

       (3)  In the iterator mode, due to the introduction of the abstraction layer, it is very convenient to add new aggregate classes and iterator classes, without modifying the original code, and meeting the requirements of the "open-closed principle".

 

       2.  Major Disadvantages

       The main disadvantages of the iterator pattern are as follows:

       (1)  Since the iterator mode separates the responsibilities of storing data and traversing data, adding a new aggregation class requires adding a new iterator class correspondingly, and the number of classes increases in pairs, which increases the complexity of the system to a certain extent .

       (2)  The design of abstract iterators is difficult, and it is necessary to fully consider the future expansion of the system. For example, JDK 's built-in iterator Iterator cannot implement reverse traversal. If it needs to implement reverse traversal, it can only be achieved through its subclass ListIterator , etc. The ListIterator iterator cannot be used to manipulate aggregate objects of type Set . When customizing iterators, it is not trivial to create a comprehensive abstract iterator.

 

       3.  Applicable scenarios

       Consider using the iterator pattern in the following situations:

       (1)  Access the contents of an aggregate object without exposing its internal representation. Separating the access of the aggregate object from the storage of the internal data makes it unnecessary to know its internal implementation details when accessing the aggregate object.

       (2)  It is necessary to provide multiple traversal methods for an aggregate object.

       (3)  Provide a unified interface for traversing different aggregate structures, and provide different traversal methods for different aggregate structures in the implementation class of the interface, and the client can operate the interface consistently.





Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325447684&siteId=291194637