前言:为什么要使用迭代器模式?什么时候使用迭代器模式?弄清楚这两个问题,就能明白什么是迭代器模式。
场景一:
遍历书架对象,将图书名按照顺序打印出来。且根据业务要求,书架一旦创建,能存放书的数量是固定的。
一般的实现方式如下
书类:
public class Book {
private String bookName;
public Book(String bookName) {
this.bookName = bookName;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
}
书架类:
public class BookShelf {
private Book[] books;
private int last =0;
public BookShelf(int maxsize) {
this.books = new Book[maxsize];
}
public void appendBook(Book book){
this.books[last] = book;
last++;
}
public Book[] getBooks() {
return books;
}
public void setBooks(Book[] books) {
this.books = books;
}
}
实现代码:
public class Test {
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf(4);
bookShelf.appendBook(new Book("A"));
bookShelf.appendBook(new Book("B"));
bookShelf.appendBook(new Book("C"));
bookShelf.appendBook(new Book("D"));
for (Book book : bookShelf.getBooks()) {
System.out.println(book.getBookName());
}
}
}
场景变化:
业务升级,书架要求对书进行索引编号,且可以通过索引号取书。
修改代码:
书架类:
```
public class BookShelf {
private Map<String,Book> books;
public BookShelf() {
}
public Book getBookByKey(String key){
return books.get(key);
}
public void appendBook(Book book,String key){
books.put(key, book);
}
public Map<String, Book> getBooks() {
return books;
}
public void setBooks(Map<String, Book> books) {
this.books = books;
}
}
```
循环也要做相应的修改
假如项目里有多处这种循环,那么这些循环都要改。这里书架类和循环业务就是一个强关联的关系。
那么有没有一种办法可以去掉这种强关联,使得我们即使修改书架的实现的同时无需修改业务代码?有,迭代器模式。
设计思路:
1.凡是书架这种聚合的类,都必定存在迭代遍历需求,所以它们必须有一个方法,来获取它们自身的迭代器。于是设计一个聚合接口,接口里定义一个获取迭代器的方法,聚合类必须实现这个接口。
public interface Agregate {
public abstract Iterator iterator();
}
public class BookShelf implements Agregate {
private Book[] books;
private int last =0;
public BookShelf(int maxsize) {
this.books = new Book[maxsize];
}
public Book getBookAt(int index){
return books[index];
}
public void appendBook(Book book){
this.books[last] = book;
last++;
}
public Book[] getBooks() {
return books;
}
public void setBooks(Book[] books) {
this.books = books;
}
@Override
public Iterator iterator() {
return null;//待定
}
}
2.创建迭代器的接口以及书架的迭代器实现类
public interface Iterator {
public abstract boolean hasNext();
public abstract Object next();
}
public class BookShelfIterator implements Iterator {
private BookShelf bookShelf;
private int index;
public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
}
@Override
public boolean hasNext() {
if (index < bookShelf.getBooks().length){
return true;
}
return false;
}
@Override
public Object next() {
Book book = bookShelf.getBookAt(index);
index++;
return book;
}
}
书架类加上返回具体迭代器的代码。
@Override
public Iterator iterator() {
return new BookShelfIterator(this);
}
遍历实现
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf(4);
bookShelf.appendBook(new Book("A"));
bookShelf.appendBook(new Book("B"));
bookShelf.appendBook(new Book("C"));
bookShelf.appendBook(new Book("D"));
Iterator iterator = bookShelf.iterator();
while (iterator.hasNext()){
Book book = (Book) iterator.next();
System.out.println(book.getBookName());
}
}
如图:
当我修改书架的实现的时候,只需要修改书架迭代器的代码即可,而不需要修改业务的代码。
总结:
迭代器模式就是将聚合类的遍历业务抽取出来封装成一个迭代器,用迭代器代替一般的遍历方法,从而代码进行解耦,并且提高了代码的复用性。