迭代子(Iterator)模式【行为模式第五篇】
迭代子(Iterator)模式:
迭代子模式又叫游标(Cursor)模式,是对象的行为模式。迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象。
多个对象聚在一起形成的总体称之为聚集(Aggregate),聚集对象是能够包容一组对象的容器对象。聚集依赖于趋集结构的抽象化,具体复杂性
和多样性。数组就是最基本的聚集,也就是其他的java聚集对象的设计基础。
java聚集(Collection)对象是实现了共同的java.util.Collection接口的对象,是java语言对聚集概念的直接支持。
聚集对象必须提供适当的方法,允许客户端能够按照一个线性顺序遍历所有的元素对象,把元素对象提取出来或者删除掉等。一个使用聚集的系统
必然会使用这些方法操控聚集对象,因而在使用聚集的系统演化过程中,会出现两类问题:
(1)迭代逻辑没有改变,但是需要将一种聚集换成另一种聚集。因为不同的聚集具有不同的遍历接口,所以需要修改客户端代码,以便
将已有的迭代调用换成新聚集对象所要求的接口。
(2)聚集不会改变,但是迭代方式需要改变。比如原来只需要读取元素和删除元素,但现在需要增加新的元素;或者原来的迭代仅仅遍历
所有的元素,而现在则需要对元素加以过滤等。这时就只好修改聚集对象,修改已有的遍历方法,或者增加新的方法。
迭代子模式涉及到的几个角色:
1、抽象《迭代子》角色:此抽象角色定义出遍历元素所需的接口。
2、具体《迭代子》角色:此角色实现了Iterator接口,并保持迭代过程中的游标位置。
3、聚集角色:此抽象角色给出创建《迭代子》对象的接口。
4、具体聚集角色:实现了创建《迭代子》对象的接口,返回一个合适的具体《迭代子》实例。
5、客户端角色:持有对聚集及其《迭代子》对象的引用,调用迭代子对象的迭代接口,也有可能通过迭代子操作聚集元素的增加和删除。
宽接口和窄接口:
1、宽接口:如果一个聚集的接口提供了可以用来修改聚集元素的方法,这个接口就是所谓的宽接口
这种提供宽接口的聚集叫做白箱聚集。聚集对象向外界提供同样的宽接口。
2、窄接口:与上反之。
这种同时保证聚集对象的封装和迭代子功能的实现的方案叫做黑箱实现方案。
白箱聚集(外禀迭代子)://抽象聚集角色public abstract class Aggregate{//工厂方法返回一个迭代子public Iterator createIterator(){return null;}}//抽象迭代子角色public interface Iterator{//迭代方法:移动到第一个元素void first();//迭代方法:移动到下一个元素void next();//迭代方法:是否是最后一个元素boolean isDone();//迭代方法:返回当前元素Object currentItem(); }//具体聚集角色public class ConcreteAggregate extends Aggregate{private Object[] obj = {"Monk Tang","Monkey","Pigsy","Sandy","Horse"};//工厂方法:返回一个迭代子对象public Iterator creteIterator(){return new ConcreteIterator(this);}//取值方法:向外界提供聚集元素public Object getElement(int index){if(index < obj.length){return obj[index];}else{return null;}}//取值方法,向外界提供聚集大小public int size(){return obj.length;}}如果一个对象的内部状态在对象被创建之后就不再变化,这个对象就称为不变对象。如果一个聚集对象的内部状态可以改变的话那么在迭代过程中,一旦聚集元素发生改变(比如一个元素被删除,或者一个新的元素被加进来),就会影响到迭代过程,使迭代无法给出正确的结果。//具体《迭代子》角色public class ConcreteIterator implements Iterator{private ConcreteAggregate agg;private int index = 0;private int size = 0;public ConcreteIterator(ConcreteAggregate agg){this.agg = agg;size = agg.size();index= 0;}public void first(){index= 0;}public void next(){if(index < size){index++;}}public boolean isDone(){return (index >= size);}public Object currentItem(){return agg.getElement(index);}}//客户端public class Client{private Iterator it;private Aggregate agg = new ConcreteAggregate();public void operation(){it = agg.createIterator();while(!it.isDone()){System.out.println(it.currentItem().toString());it.next();}}public static void main(String args[]){Client client = new Client();client.operation();}}
//抽象聚集public abstract class Aggregate{//工厂方法,返还一个迭代子对象public abstract Iterator createIterator();}//抽象迭代子public interface Iterator{//迭代方法:移动到第一个元素void first();void next();boolean isDone();Object currentItem();}//具体聚集public class ConcreteAggregate extends Aggregate{private Object[] obj = {"Monk Tang","Monkey","Pigsy","Sandy","Horse"};public Iterator createIterator(){return new ConcreteIterator();}private class ConcreteIterator implements Iterator{private int currentIndex = 0;public void first(){currentIndex = 0;}public void next(){if(currentIndex < obj.length){currentIndex ++;}}public boolean isDone(){return (currentIndex == obj.length);}public Object currentItem(){return obj[currentIndex];}}}public class Client{private Iterator it;private Aggregate agg = new ConcreteAggregate();public void operation(){it = agg.createIterator();while(it.isDone){System.out.println(it.currentItem().toString());it.next();}}public static void main(String args[]){Client client = new Client();client.operation();}}
一个例子:(关于搜索两警察的购物)//购物框抽象类public abstract class Purchase{private Vector elements = new Vector(5);//工厂方法:提供迭代子的实例public abstract Iterator createIterator();//聚集方法:将一个新元素增加到聚集的最后面public void append(Object anObj){elements.addElement(anObj);}//聚集方法:删除一个方法public void remove(Object anObj){elements.removeElement(anObj);}public Object currentItem(int n){return elements.elementAt(n);}public int count(){return elements.size();}}//具体聚集类public class PurchaseOfCopA extends Purchase{public PurchaseOfCopA(){}public Iterator createIterator(){return new ForwardIterator(this);}}public class PurchaseOfCopB extends Purchase{public PurchaseOfCopB(){}public Iterator createIterator(){return new BackwardIterator(this);}}//迭代子接口public interface Iterator{void first();void next();boolean isDone();Object currentItem();}//具体迭代子public class ForwardIterator implements Iterator{private int state;private Purchase obj;public ForwardIterator(Purchase anObj){obj = anObj;}public void first(){state = 0;}public void next(){if(!isDone()){state++;}}public boolean isDone(){if(state > obj.count()-1){return true;}return false;}public Object currentItem(){return obj.currentItem(state);}}public class BackwardIterator implements Iterator{private int state;private Purchase obj;public BackwardIterator(Purchase anObj){obj = anObj;}public void first(){state = obj.count()-1;}public void next(){if(!isDone()){state --;}}public boolean isDone(){if(state > 1){return true;}return false;}public Object currentItem(){return obj.currentItem(state);}}