- 论坛徽章:
- 0
|
Iterator Design pattern(一)里面说了,聚集类对外界有两种接口,一种宽接口,一种窄接口,1,在(一)里面介绍的是宽接口,将迭代器放在类的外面,使用Aggregate来依赖Iterator类。2,如果外界对于聚集类有add(),remove(),set()等等方法的话,对于迭代器就有可能产生错误信息。
对于Iterator主要存在两个问题。一个是对外的接口的大小。一个是聚集类里面的数据改变的时候(add,remove,set),迭代子要做的事情。
首先是数据改变的时候:
对于静态迭代子和动态迭代子的区别,在于静态迭代子将聚集类深拷贝(聚集类数据数值全copy),而动态迭代子将聚集类浅拷贝(只是copy引用)。所以使用静态迭代子的时候就不害怕当出现那些操作的时候,迭代器出现问题;而动态迭代子在聚集类里面数据改变的时候,迭代子如果未反应过来,就会出现问题。
(FailFast)如果当一个算法开始之后,它的运算环境发生变化,使得算法无法进行必须的调整时,这个算法就应当发出故障信号。failFast的概念。
JDK里面也有类实现了FailFast的功能,查看java.util.AbstractList里面的内部类ListItr里面就有一个checkForComodification()方法来检查迭代器里面的聚集类有没有 不是通过迭代器改变数据的操作。就是说直接从外界对聚集类里面的数据进行改变。如果存在就抛出一个异常ComcurrentModificationException,
这里我也存在问题?为什么动态迭代子会出现问题,外界直接对聚集类的改变就会出现问题。是出现什么问题?
也许在实战中会找到答案....
迭代子模式操作的是一个游标。A用户在遍历的时候游标指在4的地方,B在直接对聚集类里面数据增加一个数据。加在第一个。那我们再往下走的时候游标不就是在以前在3的值得地方。
这只是我个人理解,而且貌似有点问题,这更多像是数据加锁的问题的样子。
看下窄接口的Iterator,这里是对外接口的大小。
/**
* 这个接口还是用来得到Iterator.不过是在内部产生自己的Iterator而不用再配套的使用。
* @author Administrator
*
*/
public interface Aggregate {
public Iterator createIteratot();
}
import java.util.Vector;
public class BookShelf implements Aggregate{
private VectorBook> books=new VectorBook>();
private int index;
@Override
public Iterator createIteratot() {
return new BookShelfIterator();
}
public void appendBook(Book book){
books.add(book);
}
public class BookShelfIterator implements Iterator{
public BookShelfIterator(){
index=0;
}
public Object Next() {
Book book=(Book)books.get(index);
System.out.println("index:"+index);
index++;
return book;
}
@Override
public boolean hasNext() {
if(index>=books.size())
return false;
else
return true;
}
}
}
与宽接口最大的不同在于:窄接口讲Iterator放在聚集类里面去了,也就是说通过Iterator来访问。不过这里还是把appendBook()放在外面,并没有放在内部类里面。
这里我就有一个问题。将Iterator放在内部的好处在于?清晰明确?对于一种类型的数据只有一种遍历,可是如果我们将Vector类型换成Array的类型不也一样的是在BookShelf里面增加一个不同的Iterator实现类。我开始怀疑这个的好处在于哪里?在之前我们讨论使用Iterator的好处在于将for()里面的数据类型隐藏,使用next().这是改变聚集里面数据类型的好处。还有另外一些好处,如果迭代的方式改变了。我们只需要引进另外一个独立的迭代子对象就可以了。
哦,对了,放在内部的好处,在于,如果我们在外面的话,聚集类提供给Iterator的接口和提供给外界client的一样的,也就是说都是宽接口。如果放在内部的话,Iterator就可以直接调用里面的方法,而不要聚集类提供接口出来。也就是说对Iterator我们全部的方法,而对于client只有我们的public的方法。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/66973/showart_1300647.html |
|