系列文章
【设计模式】七大设计原则
【设计模式】第一章:单例模式
【设计模式】第二章:工厂模式
【设计模式】第三章:建造者模式
【设计模式】第四章:原型模式
【设计模式】第五章:适配器模式
【设计模式】第六章:装饰器模式
【设计模式】第七章:代理模式
【设计模式】第八章:桥接模式
【设计模式】第九章:外观模式 / 门面模式
【设计模式】第十章:组合模式
【设计模式】第十一章:享元模式
【设计模式】第十二章:观察者模式
【设计模式】第十三章:模板方法模式
【设计模式】第十四章:策略模式
【设计模式】第十五章:责任链模式
【设计模式】第十六章:迭代器模式
【设计模式】第十七章:状态模式
【设计模式】第十八章:备忘录模式
【设计模式】第十九章:访问者模式
【设计模式】第二十章:解释器模式
【设计模式】第二十一章:命令模式
【设计模式】第二十二章:中介者模式
文章目录
- 系列文章
- 一、定义
- 二、角色分类
- 三、实现方式
- UML图
- 具体实现
- 四、应用场景
- 五、优缺点
- 优点
- 缺点
一、定义
摘自百度百科: 提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。
二、角色分类
抽象迭代器(Iterator)
定义了访问和遍历元素的接口,声明了用于遍历数据元素的方法
具体迭代器(Concrete Iterator)
实现了抽象迭代器,完成遍历数据元素的具体实现方法,同时在迭代器中通过游标来记录在聚合对象中当前的所处位置,游标通常是一个非负整数
抽象聚合类(Aggregate)
用于存储和管理元素对象,声明了创建迭代器对象的方法,充当抽象迭代器工厂使用
具体聚合类(Concrete Aggregate)
实现了抽象聚合类中声明的创建迭代器对象的方法,该方法返回一个于该具体聚合类对应的具体迭代器实例
客户角色(Client)
具体调用方法的角色
三、实现方式
UML图
具体实现
假如我们有一个场景为:医院看病时需要挂号,按照挂号号码来看病,就可以使用迭代器模式实现
/**
* 病号实体类
*/
@Data
@ToString
public class Patient {
/**
* 病人姓名
*/
private String name;
/**
* 挂号号码
*/
private Integer number;
public Patient(String name, Integer number) {
this.name = name;
this.number = number;
}
public void diagnosis() {
System.out.println("医生你好,我是第" + this.number + "号病人" + this.name)
}
}
抽象聚合类(Aggregate)
public interface Aggregate {
void addPatient(Patient patient);
void removePatient(Patient patient);
PatientIterator createPatientIterator();
}
具体聚合类(Concrete Aggregate)
public class ConcreteAggregate implements Aggregate {
// 病人列表
private List<Patient> list;
public ConcreteAggregate() {
this.list = new ArrayList<>();
}
@Override
public void addPatient(Patient patient) {
this.list.add(patient);
}
@Override
public void removePatient(Patient patient) {
this,list.remove(patient);
}
@Override
public PatientIterator createPatientIterator() {
return new ConcreteIterator(this.list);
}
}
抽象迭代器(Iterator)
public interface Iterator {
boolean hasNext();
Patient next();
}
具体迭代器(Concrete Iterator)
public class ConcreteIterator implements Iterator {
private List<Patient> list;
private int position = 0;
private Patient currentPatient;
public ConcreteIterator(List<Patient> list) {
this.list = list;
}
@Override
public boolean hasNext() {
return position < list.size;
}
@Override
public Patient next(){
currentPatient = list.get(position);
position++;
return currentPatient;
}
}
客户角色(Client)
public class Client {
public static void main(String[] args) {
Aggregate doctorA = new ConcreteAggregate();
doctorA.addPatient(new Patient("张三", 1));
doctorA.addPatient(new Patient("李四", 2));
doctorA.addPatient(new Patient("王五", 3));
doctorA.addPatient(new Patient("赵六", 4));
Iterator iterator = doctorA.createPatientIterator();
while (iterator.hasNext()) {
Patient patient = iterator.next();
patient.diagnosis();
}
}
}
运行结果
医生你好,我是第1号病人张三
医生你好,我是第2号病人李四
医生你好,我是第3号病人王五
医生你好,我是第4号病人赵六
四、应用场景
以下部分内容摘自菜鸟教程
意图: 提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
主要解决: 不同的方式来遍历整个整合对象。
何时使用: 遍历一个聚合对象。
如何解决: 把在元素之间游走的责任交给迭代器,而不是聚合对象。
关键代码: 定义接口:hasNext, next。
应用实例: JAVA 中的 iterator。
使用场景:
- 访问一个聚合对象的内容而无须暴露它的内部表示。
- 需要为聚合对象提供多种遍历方式。
- 为遍历不同的聚合结构提供一个统一的接口。
注意事项: 迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。
五、优缺点
优点
- 它支持以不同的方式遍历一个聚合对象。
- 迭代器简化了聚合类。
- 在同一个聚合上可以有多个遍历。
- 在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
缺点
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。