设计模式之迭代器模式
迭代器模式(Iterator),其含义是提供一种方法顺序访问一个聚合对象中的各个元素,而又不需暴露该对象的内部表示。这一模式的关键思想是将对列表的访问和遍历从列表对象中分离出来并放入一个迭代器对象中。迭代器类定义了一个访问该列表元素的接口。可以理解为我们常见的java集合中的Iterator接口,非常类似。
其适用性:
访问一个聚合对象的内容而无需暴露它的内部表示,
支持对聚合对象的多种遍历,
为遍历不同的聚合结构提供一个统一的接口(即,支持多态迭代)。
其结构图:
迭代器和列表式耦合在一起的,而且客户对象必须知道遍历的是一个列表而不是其他聚合结构,我们在使用时其实有两个迭代器,一个是外部迭代器,另一个是内部迭代器,外部迭代器是由客户端主动推进遍历的步伐,显示地向迭代器请求下一个元素,而内部迭代器客户只需向其提交一个代执行的操作,而迭代器将对聚合中的每一个元素实施该操作。
在实现时, Iterator类有一个属性是Aggregate的实例,该方式是对象适配器的运用,Iterator的相关操作都是底层通过Aggregate的实例来实现的。如:
package org.designpattern.behavioral.iterator;
public abstract class Iterator {
protected Aggregate aggregate;
protected int index;
public Aggregate getAggregate() {
return aggregate;
}
public void setAggregate(Aggregate aggregate) {
this.aggregate = aggregate;
}
public abstract void first();
public abstract void next();
public abstract void last();
public abstract boolean isDone();
public abstract Object currentItem();
}
public abstract class Iterator {
protected Aggregate aggregate;
protected int index;
public Aggregate getAggregate() {
return aggregate;
}
public void setAggregate(Aggregate aggregate) {
this.aggregate = aggregate;
}
public abstract void first();
public abstract void next();
public abstract void last();
public abstract boolean isDone();
public abstract Object currentItem();
}
Aggregate定义接口操作(在此略去),由自己的实现类实现:
package org.designpattern.behavioral.iterator;
import java.util.ArrayList;
public class ConcreteAggregate extends Aggregate{
private Object[] objs;
public ConcreteAggregate(){
this.objs = new Object[32];
this.size = 0;
}
@Override
public Iterator createIterator() {
Iterator iterator = new ConcreteIterator();
iterator.setAggregate(this);
return iterator; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public Object getItem(int index) {
return this.objs[index]; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public int getSize() {
return this.size ; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void addObject(Object obj) {
this.objs[this.size] = obj;
this.size++;
//To change body of implemented methods use File | Settings | File Templates.
}
}
import java.util.ArrayList;
public class ConcreteAggregate extends Aggregate{
private Object[] objs;
public ConcreteAggregate(){
this.objs = new Object[32];
this.size = 0;
}
@Override
public Iterator createIterator() {
Iterator iterator = new ConcreteIterator();
iterator.setAggregate(this);
return iterator; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public Object getItem(int index) {
return this.objs[index]; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public int getSize() {
return this.size ; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void addObject(Object obj) {
this.objs[this.size] = obj;
this.size++;
//To change body of implemented methods use File | Settings | File Templates.
}
}
Iterator的子类操作均是通过Aggregate的实现类来实现:
package org.designpattern.behavioral.iterator;
public class ConcreteIterator extends Iterator {
public ConcreteIterator(){
this.index = 0;
}
@Override
public Object currentItem() {
return this.getAggregate().getItem(this.index); //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void first() {
this.index = 0;
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void next() {
if(this.index < this.getAggregate().getSize()){
this.index ++;
}
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void last() {
this.getAggregate().getSize();
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public boolean isDone() {
return this.index == this.getAggregate().getSize(); //To change body of implemented methods use File | Settings | File Templates.
}
public class ConcreteIterator extends Iterator {
public ConcreteIterator(){
this.index = 0;
}
@Override
public Object currentItem() {
return this.getAggregate().getItem(this.index); //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void first() {
this.index = 0;
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void next() {
if(this.index < this.getAggregate().getSize()){
this.index ++;
}
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void last() {
this.getAggregate().getSize();
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public boolean isDone() {
return this.index == this.getAggregate().getSize(); //To change body of implemented methods use File | Settings | File Templates.
}
}
客户端测试类就可以直接像使用普通的迭代器一样使用了。由此看迭代器将具体的集合类和迭代类分离开来,使用迭代器和具体集合类的复用性更佳,且外界代码使用时可以使用迭代器遍历集合,从而无需关心集合的内部细节。