基本需求:
- 展示一个学校的结构,比如一个学校下面有多个学院,学院下面有多个系,对其节点主要是遍历,与组合模式略有不同
传统方案:
- 学校<-学院<-系 依次继承
- 这种方式,在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系,因此这种方案,不能很好实现的遍历的操作,并且他们之间也没有继承关系,使用继承并不合适
基本介绍:
-
迭代器模式(Iterator)是常用的设计模式,属于行为型模式,这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示
-
如果我们的集合元素是用不同的方式实现的,有数组,还有java的集合类,或者还有其他方式,当客户端要遍历这些集合元素的时候就要使用多种遍历方式,而且还会暴露元素的内部结构,可以考虑使用迭代器模式解决
-
迭代器模式提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构
-
把在元素之间游走的责任交给迭代器,而不是聚合对象
-
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性
-
UML类图(原理)

- 说明
- Iterator:迭代器接口,直接使用JDK提供的即可提供,含有hasNext,next,remove
- ConcreteIterator:具体的迭代器类,进行元素迭代,其内部元素的以不同的方式进行存储,例如数组、list等
- Aggregate:一个统一的聚合接口,将客户端和具体聚合解耦,进行元素的存储
- ConcreteAggreage:具体的聚合持有对象集合,并提供一个方法,返回一个迭代器,该迭代器可以正确遍历集合,和ConcreteIterator一一对应
- Element:集合内部所存储的元素
- 实际情况中一般将ConcreteIterator作为内部类放入ConcreteAggreage类中,直接省去了元素集合elementes的传递
-
UML类图(案例)

- 说明
-
代码实现
-
迭代器类不作为持有迭代集合类的内部类
-
@Data
@AllArgsConstructor
public class Department {
// 迭代器内部元素
private String name;
private String description;
}
-
public class ComputerCollegeIterator implements Iterator {
// 计算机学院迭代器,元素使用数组存储 一般会将迭代器实现类作为需要迭代对象的内部类
private Department[] departments;
// 当前位置指针
private int index = 0;
public ComputerCollegeIterator(Department[] departments) {
this.departments = departments;
}
// 判断是否有下一个元素
@Override
public boolean hasNext() {
return !(this.index >= this.departments.length);
}
// 返回下一个元素
@Override
public Department next() {
return this.departments[this.index++];
}
@Override
public void remove() {
// 移除方法空实现
}
}
-
public class InfoCollegeIterator implements Iterator {
// 信息工程学院迭代器,元素使用List集合存储 一般会将迭代器实现类作为需要迭代对象的内部类
private List<Department> departments;
// 当前位置指针
private int index = 0;
public InfoCollegeIterator(List<Department> departments) {
this.departments = departments;
}
// 判断是否有下一个元素
@Override
public boolean hasNext() {
return !(this.index >= this.departments.size());
}
// 返回下一个元素
@Override
public Department next() {
return this.departments.get(this.index++);
}
@Override
public void remove() {
// 移除方法空实现
}
}
-
public interface College {
// 学院接口
// 获取学院名称
String getName();
// 给学院内部添加系
void addDepartment(String name,String description);
// 获取该学院所对应的迭代器
Iterator createIterator();
}
// 实现类一 计算机学院
class ComputerCollege implements College {
// 存储内部元素的集合,用于获取迭代器
private Department[] departments;
// 当前元素位置指针
private int index;
public ComputerCollege() {
this.departments = new Department[5];
this.index = 0;
addDepartment("Java专业","Java专业 ");
addDepartment("PHP专业","PHP专业 ");
addDepartment("大数据专业","大数据专业");
}
@Override
public String getName() {
return "计算机学院";
}
@Override
public void addDepartment(String name,String description) {
Department department = new Department(name,description);
this.departments[this.index++] = department;
}
@Override
public Iterator createIterator() {
return new ComputerCollegeIterator(this.departments);
}
}
// 实现类二 信息工程学院
class InfoCollege implements College {
// 存储内部元素的集合,用于获取迭代器
private List<Department> departments;
public InfoCollege() {
this.departments = new ArrayList<Department>();
addDepartment("信息安全专业","信息安全专业");
addDepartment("网络安全专业","网络安全专业");
addDepartment("服务器安全专业","服务器安全专业");
}
@Override
public String getName() {
return "信息工程学院";
}
@Override
public void addDepartment(String name,String description) {
this.departments.add(new Department(name,description));
}
@Override
public Iterator createIterator() {
return new InfoCollegeIterator(this.departments);
}
}
-
public class OutputImpl {
// 输出迭代器元素内部的实现类
private List<College> colleges;
public OutputImpl(List<College> colleges) {
this.colleges = colleges;
}
public void printCollege() {
// 获取List集合内部的迭代器
Iterator<College> iterator = colleges.iterator();
while (iterator.hasNext()) {
College college = iterator.next();
System.out.println("======" + college.getName() + "======");
// 获取学院内部系的迭代器进行迭代输出 而不需要知道元素再内部以什么形式的集合存在,统一了遍历方式
printDepartment(college.createIterator());
}
}
private void printDepartment(Iterator iterator) {
while (iterator.hasNext()) {
Department department = (Department) iterator.next();
if (null != department) {
System.out.println(department.getName() + "-----" + department.getDescription());
}
}
}
}
-
public class Client {
public static void main(String[] args) {
// 创建学院的集合
List<College> colleges = new ArrayList<College>();
colleges.add(new ComputerCollege());
colleges.add(new InfoCollege());
// 创建输出类 并迭代输出学院及其下面的系
OutputImpl output = new OutputImpl(colleges);
output.printCollege();
}
}
-
迭代器类作为持有迭代集合类的内部类
-
// 实现类一 计算机学院
public class ComputerCollege implements College {
// 存储内部元素的集合,用于获取迭代器
private Department[] departments;
// 当前元素位置指针
private int index;
public ComputerCollege() {
this.departments = new Department[5];
this.index = 0;
addDepartment("Java专业",description);
this.departments[this.index++] = department;
}
@Override
public Iterator createIterator() {
return new ComputerCollegeIterator();
}
// 迭代器类作为持有迭代集合类的内部类
private class ComputerCollegeIterator implements Iterator {
// 计算机学院迭代器,元素使用数组存储 一般会将迭代器实现类作为需要迭代对象的内部类
// 当前位置指针
private int index = 0;
// 判断是否有下一个元素 直接使用上层类的元素集合即可
@Override
public boolean hasNext() {
return !(this.index >= ComputerCollege.this.departments.length);
}
// 返回下一个元素 直接使用上层类的元素集合即可
@Override
public Department next() {
return ComputerCollege.this.departments[this.index++];
}
@Override
public void remove() {
// 移除方法空实现
}
}
}
-
// 实现类二 信息工程学院
public class InfoCollege implements College {
// 存储内部元素的集合,用于获取迭代器
private List<Department> departments;
public InfoCollege() {
this.departments = new ArrayList<Department>();
addDepartment("信息安全专业",description));
}
@Override
public Iterator createIterator() {
return new InfoCollegeIterator();
}
// 迭代器类作为持有迭代集合类的内部类
private class InfoCollegeIterator implements Iterator {
// 信息工程学院迭代器,元素使用List集合存储 一般会将迭代器实现类作为需要迭代对象的内部类
// 当前位置指针
private int index = 0;
// 判断是否有下一个元素 直接使用上层类的元素集合即可
@Override
public boolean hasNext() {
return !(this.index >= InfoCollege.this.departments.size());
}
// 返回下一个元素 直接使用上层类的元素集合即可
@Override
public Department next() {
return InfoCollege.this.departments.get(this.index++);
}
@Override
public void remove() {
// 移除方法空实现
}
}
}
jdk源码:
注意事项:
- 提供一个统一的方法遍历对象,客户不用再考虑聚合的类型,使用一种方法就可以遍历对象了
- 隐藏了聚合的内部结构,客户端要遍历聚合的时候只能取到迭代器,而不会知道聚合的具体组成
- 提供了一种设计思想,就是一个类应该只有一个引起变化的原因(叫做单一责任原则)。在聚合类中,我们把迭代器分开,就是要把管理对象集合和遍历对象集合的责任分开,这样一来集合改变的话,只影响到聚合对象。而如果遍历方式改变的话,只影响到了迭代器
- 当要展示一组相似对象,或者遍历一组相同对象时使用,适合使用迭代器模式
- 每个聚合对象都要一个迭代器,会生成多个迭代器不好管理类
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|