【设计模式】迭代器模式
主页传送门:💁 传送
1.迭代器模式定义
迭代器模式(Iterator Pattern) 目前已经是一个没落的设计模式,基本没人会单独写一个迭代器,除非是产品性质的开发。其定义如下:
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
即:它提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节。
其通用类图如下:

2.迭代器模式的角色
在迭代器模式中是涉及到以下几个角色:
- 抽象迭代子(Iterator)角色:
此抽象角色定义出遍历元素所需的接口。 - 具体迭代子(ConcreteIterator)角色:
此角色实现了Iterator接口,并保持迭代过程中的游标位置。 - 聚集(Aggregate)角色:
此抽象角色给出创建迭代子(Iterator)对象的接口。 - 具体聚集(ConcreteAggregate)角色:
实现了创建迭代子(Iterator)对象的接口,返回一个合适的具体迭代子实例。 - 客户端(Client)角色:
持有对聚集及其迭代子对象的引用,调用迭代子对象的迭代接口,也有可能通过迭代子操作聚集元素的增加和删除。
3.迭代器模式实战案例
3.1.场景说明
用迭代器模式编写一个浏览婺源旅游风景图的程序。
分析:婺源的名胜古迹较多,要设计一个查看相关景点图片和简介的程序,用“迭代器模式”设计比较合适。
首先,设计一个婺源景点(WyViewSpot)类来保存每张图片的名称与简介;再设计一个景点集(ViewSpotSet)接口,它是抽象聚合类,提供了增加和删除婺源景点的方法,以及获取迭代器的方法。
然后,定义一个婺源景点集(WyViewSpotSet)类,它是具体聚合类,用 ArrayList 来保存所有景点信息,并实现父类中的抽象方法;再定义婺源景点的抽象迭代器(ViewSpotltemtor)接口,其中包含了查看景点信息的相关方法。
最后,定义婺源景点的具体迭代器(WyViewSpotlterator)类,它实现了父类的抽象方法;客户端程序设计成窗口程序,它初始化婺源景点集(ViewSpotSet)中的数据,并实现 ActionListener 接口,它通过婺源景点迭代器(ViewSpotlterator)来査看婺源景点(WyViewSpot)的信息。
3.2.关系类图
使用迭代器模式来实现的结构图如下:

3.3.代码实现
//相框类
public class PictureFrame extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
ViewSpotSet ag; //婺源景点集接口
ViewSpotIterator it; //婺源景点迭代器接口
WyViewSpot ob; //婺源景点类
PictureFrame() {
super("中国最美乡村“婺源”的部分风景图");
this.setResizable(false);
ag = new WyViewSpotSet();
ag.add(new WyViewSpot("江湾", "江湾景区是婺源的一个国家5A级旅游景区,景区内有萧江宗祠、永思街、滕家老屋、婺源人家、乡贤园、百工坊等一大批古建筑,精美绝伦,做工精细。"));
ag.add(new WyViewSpot("李坑", "李坑村是一个以李姓聚居为主的古村落,是国家4A级旅游景区,其建筑风格独特,是著名的徽派建筑,给人一种安静、祥和的感觉。"));
ag.add(new WyViewSpot("思溪延村", "思溪延村位于婺源县思口镇境内,始建于南宋庆元五年(1199年),当时建村者俞氏以(鱼)思清溪水而名。"));
ag.add(new WyViewSpot("晓起村", "晓起有“中国茶文化第一村”与“国家级生态示范村”之美誉,村屋多为清代建筑,风格各具特色,村中小巷均铺青石,曲曲折折,回环如棋局。"));
ag.add(new WyViewSpot("菊径村", "菊径村形状为山环水绕型,小河成大半圆型,绕村庄将近一周,四周为高山环绕,符合中国的八卦“后山前水”设计,当地人称“脸盆村”。"));
ag.add(new WyViewSpot("篁岭", "篁岭是著名的“晒秋”文化起源地,也是一座距今近六百历史的徽州古村;篁岭属典型山居村落,民居围绕水口呈扇形梯状错落排布。"));
ag.add(new WyViewSpot("彩虹桥", "彩虹桥是婺源颇有特色的带顶的桥——廊桥,其不仅造型优美,而且它可在雨天里供行人歇脚,其名取自唐诗“两水夹明镜,双桥落彩虹”。"));
ag.add(new WyViewSpot("卧龙谷", "卧龙谷是国家4A级旅游区,这里飞泉瀑流泄银吐玉、彩池幽潭碧绿清新、山峰岩石挺拔奇巧,活脱脱一幅天然泼墨山水画。"));
it = ag.getIterator(); //获取婺源景点迭代器
ob = it.first();
this.showPicture(ob.getName(), ob.getIntroduce());
}
//显示图片
void showPicture(String Name, String Introduce) {
Container cp = this.getContentPane();
JPanel picturePanel = new JPanel();
JPanel controlPanel = new JPanel();
String FileName = "src/iterator/Picture/" + Name + ".jpg";
JLabel lb = new JLabel(Name, new ImageIcon(FileName), JLabel.CENTER);
JTextArea ta = new JTextArea(Introduce);
lb.setHorizontalTextPosition(JLabel.CENTER);
lb.setVerticalTextPosition(JLabel.TOP);
lb.setFont(new Font("宋体", Font.BOLD, 20));
ta.setLineWrap(true);
ta.setEditable(false);
//ta.setBackground(Color.orange);
picturePanel.setLayout(new BorderLayout(5, 5));
picturePanel.add("Center", lb);
picturePanel.add("South", ta);
JButton first, last, next, previous;
first = new JButton("第一张");
next = new JButton("下一张");
previous = new JButton("上一张");
last = new JButton("最末张");
first.addActionListener(this);
next.addActionListener(this);
previous.addActionListener(this);
last.addActionListener(this);
controlPanel.add(first);
controlPanel.add(next);
controlPanel.add(previous);
controlPanel.add(last);
cp.add("Center", picturePanel);
cp.add("South", controlPanel);
this.setSize(630, 550);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent arg0) {
String command = arg0.getActionCommand();
if (command.equals("第一张")) {
ob = it.first();
this.showPicture(ob.getName(), ob.getIntroduce());
} else if (command.equals("下一张")) {
ob = it.next();
this.showPicture(ob.getName(), ob.getIntroduce());
} else if (command.equals("上一张")) {
ob = it.previous();
this.showPicture(ob.getName(), ob.getIntroduce());
} else if (command.equals("最末张")) {
ob = it.last();
this.showPicture(ob.getName(), ob.getIntroduce());
}
}
}
//婺源景点类
public class WyViewSpot {
private String Name;
private String Introduce;
WyViewSpot(String Name, String Introduce) {
this.Name = Name;
this.Introduce = Introduce;
}
public String getName() {
return Name;
}
public String getIntroduce() {
return Introduce;
}
}
//抽象聚合:婺源景点集接口
public interface ViewSpotSet {
void add(WyViewSpot obj);
void remove(WyViewSpot obj);
ViewSpotIterator getIterator();
}
//具体聚合:婺源景点集
publi class WyViewSpotSet implements ViewSpotSet {
private ArrayList<WyViewSpot> list = new ArrayList<WyViewSpot>();
public void add(WyViewSpot obj) {
list.add(obj);
}
public void remove(WyViewSpot obj) {
list.remove(obj);
}
public ViewSpotIterator getIterator() {
return (new WyViewSpotIterator(list));
}
}
//抽象迭代器:婺源景点迭代器接口
public interface ViewSpotIterator {
boolean hasNext();
WyViewSpot first();
WyViewSpot next();
WyViewSpot previous();
WyViewSpot last();
}
//具体迭代器:婺源景点迭代器
public class WyViewSpotIterator implements ViewSpotIterator {
private ArrayList<WyViewSpot> list = null;
private int index = -1;
WyViewSpot obj = null;
public WyViewSpotIterator(ArrayList<WyViewSpot> list) {
this.list = list;
}
public boolean hasNext() {
if (index < list.size() - 1) {
return true;
} else {
return false;
}
}
public WyViewSpot first() {
index = 0;
obj = list.get(index);
return obj;
}
public WyViewSpot next() {
if (this.hasNext()) {
obj = list.get(++index);
}
return obj;
}
public WyViewSpot previous() {
if (index > 0) {
obj = list.get(--index);
}
return obj;
}
public WyViewSpot last() {
index = list.size() - 1;
obj = list.get(index);
return obj;
}
}
// 场景类
public class PictureIterator {
public static void main(String[] args) {
new PictureFrame();
}
}
4.迭代器模式优缺点
迭代器模式有许多优点,以下是其中的一些:
- 分离集合与迭代逻辑:迭代器模式将集合对象与遍历逻辑分离,使得它们可以独立变化。集合对象只需要实现迭代器接口,而客户端只需要通过迭代器进行遍历操作,从而实现了解耦和模块化。
- 统一遍历接口:迭代器模式定义了一组统一的遍历接口,使得客户端可以以相同的方式对待不同类型的集合对象。无论是数组、链表、树状结构还是其他自定义集合,只要它们提供了符合迭代器接口的迭代器对象,就可以使用迭代器模式进行遍历,提高了代码的灵活性和可复用性。
- 简化客户端代码:使用迭代器模式可以简化客户端代码,减少了对集合内部结构的直接操作,只需要通过迭代器对象进行遍历操作。
迭代器模式的缺点主要表现在以下几个方面:
- 设计与实现成本高:迭代器模式需要实现一个迭代器接口,并且需要保证迭代器在遍历集合时的正确性,这可能会增加设计和实现的成本。
- 灵活性不足:迭代器模式对于一些不是集合的数据结构(例如链表、树等)可能不太适用,因为它们的数据访问方式可能不同,需要实现不同的迭代器接口,这可能会影响整个系统的灵活性。
- 无法直接操作集合内部结构:迭代器模式只提供了遍历集合的方式,无法直接操作集合的内部结构,例如修改、删除等操作,这可能会影响对集合的使用。
5.迭代器模式使用场景
迭代器模式主要适用于以下场景:
- 遍历多种数据结构:迭代器模式可以遍历多种数据结构,包括数组、链表、树状结构、自定义数据结构等。通过使用迭代器模式,可以使遍历操作与数据结构解耦,提高代码的可复用性和灵活性。
- 实现复杂的数据访问操作:当需要对复杂的数据结构进行访问操作时,使用迭代器模式可以使客户端代码简化,同时可以实现对数据的灵活遍历。
- 对聚合对象的多个遍历:由于迭代器模式分离了集合与遍历逻辑,因此可以在同一个聚合上可以有多个遍历操作,这有助于在多个客户端之间共享遍历逻辑。
- 对数据的修改和删除:除了遍历数据,迭代器模式还可以支持对数据的修改和删除操作。通过使用迭代器模式,客户端可以通过迭代器对象访问集合内部元素,并对其进行修改和删除。
6.迭代器模式总结
迭代器模式是一种行为型设计模式,它提供了一种方法,可以顺序访问集合对象中的各个元素,而不暴露该对象的内部表示。迭代器模式通过将集合对象的遍历行为分离出来,交给迭代器角色来完成,从而避免了容器内部细节的暴露,并符合单一职责原则。迭代器模式的核心是迭代器接口和具体迭代器角色,通过它们可以实现遍历操作的灵活性和可复用性。
总之,迭代器模式是一种非常实用的设计模式,它提供了一种灵活、可复用的方式来遍历集合对象。在实际开发中,可以根据具体的应用场景和需求来选择是否使用迭代器模式,以及如何使用迭代器模式。
如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏 🙌一起讨论
你的支持就是我✍️创作的动力! 💞💞💞
更多推荐




所有评论(0)