一、迭代器模式的概述
定义:
迭代器模式:提供一个方法顺序访问一个聚合对象中的各个元素,而又不用暴露该对象的内部表示。
二、迭代器模式的结构和实现
2.1 迭代器模式的结构
迭代器模式包含以下4个角色:
- Iterator(抽象迭代器):定义了访问和遍历元素的接口,声明了用于遍历数据元素的方法;
- ConcreteIterator(具体迭代器):实现了抽象迭代器的方法,完成对聚合对象的遍历;
- Aggregate(抽象聚合类):用于存储和管理元素对象;
- ConcreteAggregate(具体聚合类):是抽象聚合类的子类,实现了在抽象聚合类中声明的方法。
2.2 迭代器模式的实现
//抽象迭代器
/**
* 抽象迭代器
*/
public interface AbstractIterator {
//移至下一个元素
Object next();
//移至上一个元素
Object previous();
//判断是否为最后一个元素
boolean isLast();
//判断是否为第一个元素
boolean isFirst();
//获取第一个元素
Object getFistItem();
//获取最后一个元素
Object getLastItem();
}
//具体迭代器
/**
* 遥控器,充当具体迭代器
*/
public class RemoteControl implements AbstractIterator {
private List<Object> channels;//电视机的频道
private int cursor;//游标,记录当前遍历的位置
public RemoteControl(Television television) {
this.channels = television.getObjects();
cursor = 0;
}
@Override
public Object next() {
if (cursor >= channels.size() - 1) {
cursor = -1;
}
cursor++;
return channels.get(cursor);
}
@Override
public Object previous() {
if (cursor <= 0) {
cursor = channels.size();
}
cursor--;
return channels.get(cursor);
}
@Override
public boolean isLast() {
return cursor == channels.size();
}
@Override
public boolean isFirst() {
return cursor == 0;
}
@Override
public Object getFistItem() {
cursor = 0;
return channels.get(cursor);
}
@Override
public Object getLastItem() {
cursor = channels.size() - 1;
return channels.get(cursor);
}
}
//抽象聚合类
/**
* 抽象聚合类
*/
public abstract class AbstractObjectList {
private List<Object> objects = new ArrayList<>();
public AbstractObjectList(List<Object> objects){
this.objects = objects;
}
public void add(Object o){
this.objects.add(o);
}
public void remove(Object o){
this.objects.remove(o);
}
public List<Object> getObjects(){
return objects;
}
public abstract AbstractIterator createIterator();
}
//具体聚合类
/**
* 电视机,充当具体聚合类
*/
public class Television extends AbstractObjectList{
public Television(List<Object> objects) {
super(objects);
}
@Override
public AbstractIterator createIterator() {
return new RemoteControl(this);
}
}
//客户端
public class Client {
public static void main(String[] args) {
/**
* 案例需求描述:
* 电视机遥控器是一个迭代器的现实应用,通过它可以实现对电视机频道集合的遍历操作,
* 电视机可以看成一个存储频道的聚合对象。
* 使用迭代器模式模拟电视机遥控器的实现。
*/
//电视机频道
List<Object> channels = new ArrayList<>();
channels.add("CCTV-1");
channels.add("CCTV-2");
channels.add("上海卫视");
channels.add("东方卫视");
channels.add("湖南卫视");
channels.add("浙江卫视");
//电视机
Television tv = new Television(channels);
//遥控器
AbstractIterator iterator = tv.createIterator();
//获取第一个频道
System.out.println(iterator.getFistItem());
//获取最后一个频道
System.out.println(iterator.getLastItem());
//下一个频道
System.out.println(iterator.next());
System.out.println(iterator.next());
System.out.println(iterator.next());
//上一个频道
System.out.println(iterator.previous());
System.out.println(iterator.previous());
System.out.println(iterator.previous());
}
}
三、迭代器模式的优缺点和适用环境
3.1 迭代器模式的优点
- 支持以不同的方式遍历一个聚合对象,在同一个聚合对上可以定义多种遍历方式;
- 简化了聚合类;
- 增加新的聚合类和迭代器类都很方便,无需修改原有代码,满足开闭原则;
3.2 迭代器模式的缺点
- 由于迭代器模式将存储数据和遍历数据的职责分离,造成类的个数成对增加,在一定程度上增加了系统的复杂性;
- 抽象迭代器的设计难度较大,需要充分考虑到系统将来的扩展。
3.3 迭代器模式的适用环境
- 访问一个聚合对象的内容而无需暴露它的内部表示。
- 需要为一个聚合对象提供多种遍历方式
- 为遍历不同的聚合结构提供一个统一的接口,在该接口的实现类中为不同的集合结构提供不同的遍历方式,而客户端可以一致性地操作该接口。
【参考文献】:
本文是根据刘伟的《Java设计模式》一书的学习笔记,仅供学习用途,勿做其他用途,请尊重知识产权。
【本文代码仓库】:https://gitee.com/xiongbomy/java-design-pattern.git