程序员人生 网站导航

浅谈设计模式:迭代器模式(Iterator Pattern)

栏目:框架设计时间:2015-04-30 08:22:46

酷爱生活、享受文娱、专注技术,欢迎关注QGer,我们1起见证成长!
这里写图片描述

甚么是迭代器模式?

官方解释:to access the elements of an aggregate object sequentially without exposing its underlying implementation.
顺序地访问集合对象的元素并且不暴露它的内部实现

 通俗解释:假定给定1个集合对象,定义1个与之相干联的Iterator(迭代器),该迭代器能够访问集合对象的内部元素,通过迭代的方法能够依照顺序顺次访问集合对象的每个元素。

为何使用迭代器模式?

  • 它能让集合内部元素结构对客户端透明的情况下遍历该集合。保证了封装性,透明性。
  • 提供了1个统1的方法去访问你的数据对象(集合),并且你不需要知道数据对象的类型。
  • 实用性很强,得到了广泛的利用,并且拓展性很强,容易自己进行拓展。

如何使用迭代器模式?

UML图以下:
这里写图片描述
各个组件解释:

  • Iterator:抽象迭代器,定义了迭代器最基本的接口。如:hasNext()表示是不是该迭代是不是还有下1个元素,next则是返回迭代的下1个元素。

  • Aggregate:抽象集合,定义了集合的基本操作接口。如:add()向该集合增加1个原色,remove()则表示删除某个元素。

  • ComcreteAggregate:具体数据集合类,定义了集合元素的结构,操作细节。同时在类内部定义了1个具体迭代器并提供1个能够返回迭代器对象的方法。

  • ConcreteIterator:具体迭代器,通常定义在聚合类的内部,以此来到达访问聚合类内部数据结构的目的,同时实现了迭代访问聚合类元素的方法。

使用范围:

  • 当你想要在不暴露其内部表示的情况下访问1个对象集合

  • 当你想要有多种遍历方式来遍历1个对象集合,如正序、倒序、跳表访问

利用举例:
假定现在有1个学生对象集合类,客户端其实不想关心其内部细节,只需要能遍历学生对象(或学生对象的某些属性)便可。使用迭代器模式来实现这个需求。
1、定义迭代器和集合的抽象接口。

interface Iterator<T> { T next(); boolean hasNext(); } interface Collection<T> { boolean add(T element); boolean remove(T element); }

2、定义学生对象类,简明起见,不定义太多复杂属性

public class Student { private String id; private String name; public Student(String id, String name) { this.id = id; this.name = name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } }

3、实现具体学生对象聚合类,并在内部依赖定义具体迭代器。

public class StudentList implements Collection<Student> { List<Student> elementList = new ArrayList<>(); @Override public void add(Student element) { elementList.add(element); } @Override public boolean remove(Student element) { return elementList.remove(element); } public Iterator<Student> createIterator(){ return new StudentIterator(elementList); } //具体迭代器类 private class StudentIterator implements Iterator<Student> { private List<Student> students; private int position; public StudentIterator(List<Student> students) { this.students = students; this.position = 0; } @Override public Student next() { if(hasNext()) { return students.get(position++); } return null; } @Override public boolean hasNext() { return position < students.size(); } } }

4、使用客户端调用,此处mock1个测试数据,方便调用。

public class Client { public static void main(String[] args) { StudentList studentList = new StudentList(); studentList.add(new Student("001", "张3")); studentList.add(new Student("002", "李4")); studentList.add(new Student("004", "赵5")); studentList.add(new Student("004", "钱6")); Iterator<Student> iterator = studentList.createIterator(); while(iterator.hasNext()){ Student student = iterator.next(); System.out.println(student.getId() + student.getName()); } } }

注:此处的抽象迭代器、抽象集合接口,均只声明了最简单经常使用的方法,之际开发中可以根据需求增加各种各样的方法,如Java.Util里面的Iterator定义接口以下:
这里写图片描述
迭代器则可以根据具体的聚合,选择不同的遍历方式:正序、倒序、跳表等。而遍历的可以不是全部对象,也许你指向遍历对象的某个属性呢,如上例你指向要遍历学生的学号,或说学号用得最勤劳,那末你另外定义1个迭代方法nextId来遍历学生的学号呀。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐