目录
前言
关于设计模式,笔者前前后后学了不少关于这方面的书籍,每一次都有不同的收获和发现,而且像Tomcat,Spring等知名项目的源码中大量穿插各式各样的设计模式,所以想把这些记录下来,结合项目,结合源码,力求能把每一种设计模式学明白,说明白,项目里用明白。
一、什么是迭代器模式
提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示
二、UML图
三、示例程序
1、表示集合的接口
package com.as.module.iterator;
/**
* 集合接口
* @author Andy
* @date 2021/4/19 20:23
*/
public interface Aggregate {
public abstract Iterator iterator();
}
2、遍历集合的接口
package com.as.module.iterator;
/**
* 迭代器接口
* @author Andy
* @date 2021/4/19 20:24
*/
public interface Iterator {
public abstract boolean hashNext();
public abstract Object next();
}
3、表示书的类
package com.as.entity;
/**
* 图书类
* @author Andy
* @date 2021/4/19 20:17
*/
public class Book {
private String name;
public Book(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
4、表示书架的类
package com.as.module.iterator;
import com.as.entity.Book;
/**
* 书架
* @author Andy
* @date 2021/4/19 20:27
*/
public class BookShelf implements Aggregate{
private Book[] books;
private int last;
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 int getLength(){
return last;
}
@Override
public Iterator iterator() {
return new BookShelfIterator(this);
}
}
5、遍历书架的类
package com.as.module.iterator;
import com.as.entity.Book;
/**
* 书架迭代器
* @author Andy
* @date 2021/4/19 20:25
*/
public class BookShelfIterator implements Iterator{
private BookShelf bookShelf;
private int index;
public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
}
@Override
public boolean hashNext() {
if(bookShelf.getLength()>index){
return true;
}
return false;
}
@Override
public Object next() {
Book book = bookShelf.getBookAt(index);
index++;
return book;
}
}
6、测试程序行为的类
package com.as.module.iterator;
import com.as.entity.Book;
/**
* TODO
*
* @author Andy
* @date 2021/4/19 20:32
*/
public class TestIterator {
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf(4);
bookShelf.appendBook( new Book("当幸福来敲门"));
bookShelf.appendBook(new Book("彼得林奇的成功投资"));
bookShelf.appendBook(new Book("摩根财团"));
bookShelf.appendBook(new Book("国富论"));
Iterator iterator = bookShelf.iterator();
while(iterator.hashNext()){
Book book = (Book)iterator.next();
System.out.println(book.getName());
}
}
}
运行结果:
四、拓展思路与注意事项
1、不管实现如何变化,都可以使用Iterator
大家一定会想,我们遍历集合为什么不用for循环呢,而要用复杂的iterator。一个重要的理由就是,引入iterator后可以将遍历与实现分离开来
while(iterator.hashNext()){
Book book = (Book)iterator.next();
System.out.println(book.getName());
}
这里只使用了Iterator的hasNextext方法和next方法,并么有调用BookShelf的方法,也就是说,这里的while循环并不依赖于BookShelf的实现
2、难以理解抽象类和接口
难以理解抽象类和接口的人常常使用ConcreteAggregate角色和ConcreteIterator编程,而不使用Aggregate接口和Iterator接口,他们总想用具体的类来解决所有问题。但是如果只使用具体的类来解决问题,很容易导致类之间的强耦合,这种类也难以作为组件被再次利用。所以,对设计模式而言,务必牢记“不要使用具体类来编程,要优先使用抽象类和接口”
3、Aggregate和Iterator的对应
正如Aggregate和Iterator是对应的一样,ConcreteAggregate角色和ConcreteIterator这两个类也是相对应的
4、容易弄错"下一个"
next方法具体是指“返回当前的元素,并且指向下一个元素”
5、还容易弄错"最后一个"
hasNext方法在返回最后一个元素前会返回true,返回最后一个元素后则返回false。
6、多个Iterator
“将遍历功能至于Aggregate角色之外”是Iterator模式的一个特征。根据这个特征,可以针对一个ConcreteAggregate角色编写多个ConcreteIterator角色
7、迭代器的种类多种多样
(1)可以从后往前遍历
(2)可以“跳跃式”遍历
8、不需要deleteIterator
在java中,没有被使用的对象实例会被自动删除(垃圾回收,GC)。因此,在iterator中不需要与其对应的deleteIterator方法中。