定义
迭代器模式(Iterator Pattern):提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标(Cursor)。
通俗理解
物流运输货物的时候,有不同的装箱方式也有不同的卸货方式,例如啤酒之类玻璃瓶装的要轻拿轻放、电子产品也是需要轻拿轻放的、建筑钢材之类都就随意了,可以乱扔。这个方式可不能搞混了,如果啤酒采用乱扔的方式,那么运输的就不是啤酒,而是一堆玻璃渣子;如果建筑钢材还轻拿轻放,那就太浪费人力物力。
面对这种情况,我们只能谨慎,不然这这一趟运输就白跑喽。可是要做到谨慎可不是那么容易的,因为不同的货物有不同的卸货方式,而不同的卸货方式需要不同的工具,那么我们在运输的时候就需要把相应的卸货工具给带上,况且,还需要有人会用这些卸货工具,如果一个人连叉车都没用过,那么怎么可以让他开呢?
于是,又陷进了一个,增加成本的困境。
解决这种困境的方式,有一个,就是成立专门的装卸货部门。由这个部门专业进行装卸货的工作,他们有专业的工具也有专业的人,物流公司只需要把货物给运到,剩下的工作就交个装卸货部门就可以了。他们会把货物妥妥当当地放到该放到的地方上去。
迭代器模式就是这样的一个理念。装卸货和运输分割开来,运输就只管运输,而装卸货也就只是装卸货。表现在程序上,就是对象在容器存储和对象的获取分割开来,在对象的获取方面,不管底层采用怎么样的存储方式,获取的方式都是采用统一接口,不关心底层的实现是如何。就是说,不管是怎么的货物,怎么摆放到车厢当中,只要交给卸货部门,就能很好卸货。
示例
业务采用装上面的实例。
渣渣程序
数组
public class Array {
public String[] goods = new String[10];
}
程序入口
public class Main {
public static void main(String[] args) {
Array array = new Array();
array.goods[0] = "第一个货物";
array.goods[1] = "第二个货物";
array.goods[2] = "第三个货物";
System.out.println(array.goods[0]);
System.out.println(array.goods[1]);
System.out.println(array.goods[2]);
}
}
//第一个货物
//第二个货物
//第三个货物
上面程序的问题显而易见了,就是我们必须知道对象在底层的实现方式,然后我们才能够根据他的实现方式去读取他里面的内容,这是一个数组的实现,我们采用数组的读取方式,那如果是链表的实现,那么我们也得采用链表的读取方式,太浪费精力。
优化
类图
程序
Array
类不变。
迭代器接口与实现
public interface Iterator {
String first();
String next();
boolean hasNext();
}
public class ConcreteIterator implements Iterator {
private Array array;
private int cursor;
public ConcreteIterator(Array array) {
cursor = 0;
this.array = array;
}
public String first() {
cursor = 0;
return array.goods[cursor];
}
public String next() {
String currentItem = array.goods[cursor];
cursor ++;
return currentItem;
}
public boolean hasNext() {
if(array.goods[cursor] != null) {
return true;
}
return false;
}
}
程序入口
public class Main {
public static void main(String[] args) {
Array array = new Array();
array.goods[0] = "第一个货物";
array.goods[1] = "第二个货物";
array.goods[2] = "第三个货物";
Iterator iterator = new ConcreteIterator(array);
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
//第一个货物
//第二个货物
//第三个货物
优点
- 支持不同的迭代方法去访问一个容器对象;
- 简化聚合类,容器不需要提供遍历数据的方法,简化聚合类的设计;
- 存储和遍历分开,有利于解耦合。
缺点
- 存储和遍历分开,新加一个存储类就得增加一个迭代器的类,造成类的膨胀;
- 开发难度大,要考虑好扩展性。
应用场景
- 遍历容器内的对象,并不需要知道容器内部的数据结构;
- 允许对容器进行多级遍历;
- 提供一致的接口来遍历不同的实现方式的容器。
实例
JDK的java.util包,Java原生支持,foreach循环就是通过这个实现的。
程序
吐槽
就是提供统一接口来访问一个容器对象而已。
网友评论