Chinaunix首页 | 论坛 | 博客
  • 博客访问: 64545
  • 博文数量: 34
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 360
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-20 10:39
文章分类
文章存档

2010年(3)

2009年(5)

2008年(26)

我的朋友
最近访客

分类: Java

2008-10-15 12:21:33

    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 Vector<Book> books=new Vector<Book>();
   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的方法。

  

阅读(752) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~