名称:迭代器模式(Iterator Pattern),又称游标(Cursor)
模式类型:行为型模式
目的:提供一种方法顺序访问聚合对象中的元素,而不暴露其内部表示
解决问题:以不同方式遍历聚合对象
原理:聚合类中保留聚合对象存储内部数据的职责,而将遍历内部数据的职责交给迭代器来完成,以实现“单一职责”的原则
UML类图:
角色: 1.客户端角色(Client)
2.抽象聚合类(Aggregate)
3.具体聚合类(ConcreteAggregate):通过createIterator()返回给客户端对应的迭代器对象
4.抽象迭代器(Iterator)
5.具体迭代器(ConcreteIterator):在具体聚合类中实现
优点: 1.支持以不同方式遍历一个聚合对象
2.迭代器简化了聚合类
3.在同一个聚合上可以有多个遍历
4.增加新的聚合类和迭代器无需修改原有代码,满足“开闭原则”的要求
缺点:由于存储数据和便利数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,增加了系统的复杂性
示例:遥控器对电视机频道的正向遍历和逆向遍历
UML图:
代码(只实现TCL部分):
/** * @Author: Mr.Liu * @Date: 13:49 2018/6/8 * @Modified by: * @Description: 电视机(Television)——聚合类,用于储存数据 */ public interface Television { public TVIterator createIterator(); }
/** * @Author: Mr.Liu * @Date: 13:47 2018/6/8 * @Modified by: * @Description: 遥控器(TVIterator)——迭代器,实现对聚合类中数据的遍历 */ public interface TVIterator { public void setChannel(int i); //设置初始频道 public Object currentChannel(); //返回当前频道名 public void next(); //下一个频道 public void prevoius(); //上一个频道 public boolean isLast(); //是否为最后一个频道 public boolean isFirst(); //是否为第一个频道 }
/** * @Author: Mr.Liu * @Date: 13:52 2018/6/8 * @Modified by: * @Description: TCL电视机(TCLTelevision) */ public class TCLTelevision implements Television { //储存的节目单 private Object[] obj = {"CCTV1","CCTV2","CCTV3","CCTV4","CCTV5","CCTV6","CCTV7","CCTV8","CCTV9","CCTV10","CCTV11","CCTV12","CCTV13","CCTVnews"}; @Override public TVIterator createIterator() { return new TCLIterator(); } /** * @Author: Mr.Liu * @Date: 13:52 2018/6/8 * @Modified by: * @Description: TCL遥控器(TCLIterator) */ class TCLIterator implements TVIterator{ //当前频道 private int currentIndex = 0; @Override public void setChannel(int i) { this.currentIndex = i; } @Override public Object currentChannel() { return obj[currentIndex]; } @Override public void next() { if(currentIndex<obj.length){ currentIndex++; } } @Override public void prevoius() { if(currentIndex>-1){ currentIndex--; } } @Override public boolean isLast() { if(currentIndex<14){ return false; } else { return true; } } @Override public boolean isFirst() { if(currentIndex>-1){ return false; } else { return true; } } } }
/** * @Author: Mr.Liu * @Date: 14:01 2018/6/8 * @Modified by: * @Description: 客户端Client */ public class Client { public static void display(Television tv){ TVIterator tvIterator = tv.createIterator(); System.out.println("正向输出节目表:"); while(!tvIterator.isLast()){ System.out.println(tvIterator.currentChannel().toString()); tvIterator.next(); } } public static void reverseDisplay(Television tv){ TVIterator tvIterator = tv.createIterator(); tvIterator.setChannel(13); System.out.println("逆向输出节目表:"); while(!tvIterator.isFirst()){ System.out.println(tvIterator.currentChannel().toString()); tvIterator.prevoius(); } } public static void main(String[] args){ Television tv; tv = new TCLTelevision(); display(tv); System.out.println("-----------------------------"); reverseDisplay(tv); } }