1. 定义
- 提供一种方法顺序访问一个容器对象中的各个元素,而又不需要暴露该对象的内部表示
- 又称游标(Cursor)模式
2. 使用场景
- 访问一个聚合对象的内容而无须暴露它的内部表示
- 需要为聚合对象提供多种遍历方式
- 为遍历不同的聚合结构提供一个统一的接口
3. 优缺点
- 优点:
- 它支持以不同的方式遍历一个聚合对象
- 迭代器简化了聚合类
- 在同一个聚合上可以有多个遍历
- 在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码
- 缺点:
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性
4. Android源码中的使用
迭代器模式还是很常见的,我们平时使用的List,Map等集合类所包含的迭代器,数据库查询使用的Cursor都是属于迭代器模式的应用
5. 实例演示
以统计员工数据为例
- 首先创建一个员工类
class Employee {
private String name;
private int age;
private String sex;
private String job;
public Employee(String name, int age, String sex, String job) {
this.name = name;
this.age = age;
this.sex = sex;
this.job = job;
}
@Override
public String toString() {
return "员工:{" +
"姓名:'" + name + '\'' +
", 年龄:" + age +
", 性别:'" + sex + '\'' +
", 职位:'" + job + '\'' +
'}';
}
}
- 创建一个迭代器接口
interface Iterator {
//是否还有下一个元素
boolean hasNext();
//返回当前位置的元素,并将位置移至下一位
Employee next();
}
- 创建两个公司类,都持有员工的集合,但是内部实现是不同的,一个是数组,一个是List集合,都实现了上面的迭代器接口
class Company1 implements Iterator {
private List<Employee> mList = new ArrayList<>();
private int index;
public Company1() {
mList.add(new Employee("小金", 23, "男", "程序猿"));
mList.add(new Employee("小七", 20, "男", "测试"));
mList.add(new Employee("小丽", 21, "女", "UI设计师"));
mList.add(new Employee("小亮", 26, "男", "产品"));
}
public List<Employee> getEmployees() {
return mList;
}
@Override
public boolean hasNext() {
return !(index > mList.size() - 1 || mList.get(index) == null);
}
@Override
public Employee next() {
Employee employee = mList.get(index);
index++;
return employee;
}
}
class Company2 implements Iterator {
private Employee[] mArray = new Employee[4];
private int index;
public Company2() {
mArray[0] = new Employee("毛毛", 19, "男", "前端");
mArray[1] = new Employee("华仔", 21, "男", "测试");
mArray[2] = new Employee("莉莉", 23, "女", "UI设计师");
mArray[3] = new Employee("童歌", 32, "男", "产品");
}
public Employee[] getEmployees() {
return mArray;
}
@Override
public boolean hasNext() {
return !(index > mArray.length - 1 || mArray[index] == null);
}
@Override
public Employee next() {
Employee employee = mArray[index];
index++;
return employee;
}
}
- 创建一个老板类,它需要去遍历访问员工数据,里面有三个方法,分别是对数组遍历,对List遍历,以及使用迭代器遍历
class Boss1 {
public void read1(List<Employee> list) {
for (int i = 0; i < list.size(); i++) {
LjyLogUtil.i(list.get(i).toString());
}
}
public void read2(Employee[] array) {
for (int i = 0; i < array.length; i++) {
LjyLogUtil.i(array[i].toString());
}
}
public void read3(Iterator iterator) {
while (iterator.hasNext()) {
LjyLogUtil.i(iterator.next().toString());
}
}
}
- 创建实例进行遍历, 从这里就可以看出迭代器模式(read3)的好处了, 1. 实现了解耦,boss类不再持有员工的引用;2. 方便扩展,若又有个company3,4,5,6...都是不同的数据结构实现的,若是普通方法去遍历那么还要修改boss类的代码,而如果用迭代器模式实现则只需要新增的company类实现迭代器接口就好了
private void methodIteratorPattern() {
//以统计员工数据为例
Company1 company1 = new Company1();
Company2 company2 = new Company2();
Boss1 boss1 = new Boss1();
LjyLogUtil.i("----普通方式----");
boss1.read1(company1.getEmployees());
boss1.read2(company2.getEmployees());
LjyLogUtil.i("----iterator方式----");
boss1.read3(company1);
boss1.read3(company2);
}
网友评论