4.4 迭代器模式(Iterator Pattern)
-
模式动机与定义
- 模式动机
- 电视机 -- 存储电视频道的集合 -- 聚合类(Aggregate Classes)
- 电视机遥控器 -- 操作电视频道 -- 迭代器(Iterator)
- 访问一个聚合对象中的元素但又不需要暴露它的内部节后 -- 迭代器模式
- 模式定义
- 提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示
- 其别名为游标(Cursor)
- 迭代器模式是一种对象行为型模式
- 模式动机
-
模式结构与分析
-
模式结构
- 模式角色:
- Iterator: 抽象迭代器
- ConcreteIterator: 具体迭代器
- Aggregate: 抽象聚合类
- ConcreteAggregate: 具体聚合类
- 模式角色:
-
模式分析
-
聚合对象的两个职责
- 存储数据,聚合对象的基本职责
- 遍历数据,既是可变化的,又是可分离的
将遍历数据的行为从聚合对象中分离出来,封装在迭代器对象中
由迭代器来提供遍历聚合对象内部数据的行为,简化聚合对象的设计,更符合单一职责原则
-
-
模式实例与解析
-
模式效果与应用
-
模式优点
- 支持以不同的方式遍历一个聚合对象,在同一个聚合对象上可以定义多种遍历方式
- 简化了聚合类
- 由于引入了抽象层,增加新的聚合类和迭代器类都很方便,无须修改原有代码,符合开闭原则
-
模式缺点
- 在增加新的聚合类时需要对应地增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性(跟工厂方法模式一样)
- 抽象迭代器的设计难度较大,需要充分考虑到系统将来的扩展。在自定义迭代器时,创建一个考虑全面的抽象迭代器并不是一件很容易的事情
-
模式应用
- 访问一个聚合对象内容而无须暴露它的内部表示
- 需要为一个聚合对象提供多种遍历方式
- 为遍历不同的聚合结构提供一个统一的接口,在该接口的实现类中为不同的聚合结构提供不同的遍历方式,而客户端可以一致性地操作该接口
-
interface TVIterator {
void setChannel(int i);
void next();
void previous();
boolean isLast();
Object currentChannel();
boolean isFirst();
}
interface Television {
TVIterator createIterator();
}
class SkyworthTelevision implements Television {
private Object [] obj = {"CCTV-1","CCTV-2","CCTV-3","CCTV-4","CCTV-5","CCTV-6"};
@Override
public TVIterator createIterator() {
// TODO Auto-generated method stub
return new SkyworthIterator();
}
//采用内部类的形式
private class SkyworthIterator implements TVIterator {
private int currentIndex = 0;
//设置游标值
@Override
public void setChannel(int i) {
// TODO Auto-generated method stub
currentIndex = i;
}
//递增游标值
@Override
public void next() {
// TODO Auto-generated method stub
if(currentIndex<obj.length) {
currentIndex++;
}
}
//递减游标值
@Override
public void previous() {
// TODO Auto-generated method stub
if(currentIndex>=0) {
currentIndex--;
}
}
//判断游标值是不是最后一个
@Override
public boolean isLast() {
// TODO Auto-generated method stub
if(currentIndex == obj.length) {
return true;
}
else {
return false;
}
}
//返回当前游标值对应的聚合对象的值
@Override
public Object currentChannel() {
// TODO Auto-generated method stub
return obj[currentIndex];
}
//判断游标值是不是最前一个
@Override
public boolean isFirst() {
// TODO Auto-generated method stub
if(currentIndex == -1) {
return true;
}
else {
return false;
}
}
}
}
public class Client {
//正向遍历
public static void display(Television tv) {
//创建迭代器对象
TVIterator tvIterator = tv.createIterator();
while(!tvIterator.isLast()) {
System.out.println("当前节目为:" + tvIterator.currentChannel().toString() );
tvIterator.next();
}
}
//反向遍历
public static void reverseDisplay(Television tv) {
TVIterator tvIterator = tv.createIterator();
//设置迭代器游标值
tvIterator.setChannel(5);
while(!tvIterator.isFirst()) {
System.out.println("当前节目为:" + tvIterator.currentChannel().toString() );
tvIterator.previous();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建聚合类对象
Television tv = new SkyworthTelevision();
System.out.println("正向遍历");
display(tv);
System.out.println("------------------");
System.out.println("反向遍历");
reverseDisplay(tv);
}
}