Iterator 迭代器模式--隐藏访问

来源:互联网 发布:js 给div添加右键事件 编辑:程序博客网 时间:2024/06/05 20:25

1.概述
迭代器模式可以顺序访问一个容器对象中各个元素,而又不需要暴露该容器对象的内部细节。多个对象聚在一起形成的总体称之为聚集,聚集对象是能够包容一组对象的容器对象。每一个聚集对象都可以有一个或一个以上的迭代器对象,每一个迭代器的迭代状态可以是彼此对立。
相似情景:
1.假设一种场景,家兴买了一个行李箱和一个储物箱,家兴的妈妈帮家兴收拾好行李了,都放在这两个箱子里面,但是由于某种情况,家兴想知道这两个箱子的东西存放顺序和所放的东西。由于这两个箱子里面的结构不同,要想知道这些东西就必须分别打开进行查看才能达到目的。那么存在这样的解决方案,通过迭代器可以不用打开一个个进行查看就可以知道。
2.实际场景,一个对象序列和一个对象数组,如果想遍历查看序列和数组,序列就必须使用ArrayList的get(i),size()方法,数组需要length和中括号,如果使用迭代器我们只需要创建一个对象,再通过使用迭代器里面的hasNext(),next()就可以达到这样目的,我们不需要知道它里面的内部结构,只需要它是一个集合就行了。

2)解决方案和使用场景
当你需要访问一个聚集的对象,而且不管这些对象是什么都需要遍历的时候,你就要考虑到迭代器模式;当聚集有多种方式遍历时候,可以考虑迭代器模式;迭代器模式为遍历不同的聚集结构提供开始、下一个,是否结束,当前哪一项等统一接口。迭代器的相关接口一般有Iterator和IEnumerable;

3)结构
Iterator:抽象迭代器。迭代器定义访问和遍历元素的接口。
ArrayIterator:数组迭代器。实现迭代器接口,在遍历是跟踪当前聚合对象的位置。
ListIterator:序列迭代器。实现迭代器接口,在遍历是跟踪当前聚合对象的位置。
Aggregate:抽象聚合类。定义一个创建迭代器对象类。
ArrayAggregate:数组聚合类。实现创建迭代器对象,返回一个具体数组迭代器的实例。
ListAggregate:序列聚合类。实现创建迭代器对象,返回一个具体序列迭代器的实例。

4)迭代器模式XML图
这里写图片描述

5)代码实现

//聚合抽象类public abstract class Arggregate {    public abstract Iterator createIterator();}//数组聚合类public class ArrayArggregate extends Arggregate{    private Object[] ob;    public ArrayArggregate(Object[] ob){        this.ob = ob;    }    @Override    public Iterator createIterator() {        // TODO Auto-generated method stub        return new ArrayIterator(this);    }    public int size(){        return ob.length;    }    public Object[] elements(){        return ob;    }}//序列聚合类public class ListArggregate extends Arggregate{    private ArrayList<Object> list;    public ListArggregate(ArrayList<Object> list){        this.list = list;    }    @Override    public Iterator createIterator() {        // TODO Auto-generated method stub        return new ListIterator(this);    }    public int size(){        return list.size();    }    public ArrayList<Object> elements(){        return list;    }}//迭代器public interface Iterator {    public Object first();    public boolean hasNext();    public Object next();    public Object all();    public boolean remove(int i);}//数组迭代器import java.util.Arrays;public class ArrayIterator implements Iterator{    private ArrayArggregate arrayArggregate;    private int size;    private int index = 0;    private Object[] objects;    public ArrayIterator(ArrayArggregate arrayArggregate){        this.arrayArggregate = arrayArggregate;        this.size = arrayArggregate.size();        this.objects = arrayArggregate.elements();    }    @Override    public Object first() {        // TODO Auto-generated method stub        if(objects[0]==null){            return null;        }        return objects[0];    }    @Override    public boolean hasNext() {        // TODO Auto-generated method stub        if(objects[index+1]!=null){            return true;        }        return false;    }    @Override    public Object next() {        // TODO Auto-generated method stub        index+=1;        if(objects[index]==null){            return null;        }        return objects[index];    }    @Override    public String all() {        // TODO Auto-generated method stub        return Arrays.toString(objects);    }    @Override    public boolean remove(int i) {        // TODO Auto-generated method stub        if(i<=0){            throw new IllegalStateException            ("You can't remove an item until you've done at least one next()");        }        if(objects[i-1]!=null){            for(int j = i-1;j<size-1;j++){                objects[j]= objects[j+1];            }            size--;            objects[size-1]=null;        }        return true;    }}//序列迭代类import java.util.ArrayList;public class ListIterator implements Iterator{    private ListArggregate list;    private int size;    private int index = 0;    private ArrayList<Object> lists;    public ListIterator(ListArggregate list){        this.list = list;        size = list.size();        lists = list.elements();    }    @Override    public Object first() {        // TODO Auto-generated method stub        if(lists.get(0)==null){            return null;        }        return lists.get(0);    }    @Override    public boolean hasNext() {        // TODO Auto-generated method stub        if(lists.get(index+1)==null){            return false;        }        return true;    }    @Override    public Object next() {        // TODO Auto-generated method stub        index+=1;        if(lists.get(index)==null){            return null;        }        return lists.get(index);    }    @Override    public Object all() {        // TODO Auto-generated method stub        return lists;    }    @Override    public boolean remove(int i) {        // TODO Auto-generated method stub        if(i<=size){        lists.remove(i);        return true;        }        return false;    }}//客户端import java.util.ArrayList;public class Client {    public static void main(String[] args) {        // TODO Auto-generated method stub        //数组迭代器        String[] prams = {"yatming","juddy","john","amy"};         Arggregate argg = new ArrayArggregate(prams);        Iterator it1 = argg.createIterator();        System.out.println(it1.first());        if(it1.hasNext()){            System.out.println(it1.next());        }        System.out.println(it1.all());        //        ArrayList<Object> List = new ArrayList<Object>();         List.add("家兴");        List.add(1);        List.add("家敏");        Arggregate argg1 = new ListArggregate(List);        Iterator it2 = argg1.createIterator();        it2.first();        if(it2.hasNext()){            System.out.println(it1.next());        }        it2.remove(2);        System.out.println(it2.all());    }}

程序运行结果
yatming
juddy
[yatming, juddy, john, amy]
john
[家兴, 1]

6)结果分析
1.聚合的数据已经被封装起来了,客户端不知道里面的逻辑,符合单一职责原则,提高后期的扩展性。
2.只要实现迭代器,我们就可以使用迭代器查询里面的方法,包括删除等行为。
3.共同实现一个迭代器接口,可以实现多个具体类。

7)迭代器模式缺点
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

8)与其它模式
1. 工厂方法模式
多态迭代器靠Factory Method来例化适当的迭代器子类。
2.组合模式:通常与组合模式一起使用,将存储数据和遍历数据一起分离,避免子类爆炸式增长
3.备忘录模式:常与迭代器模式一起使用。迭代器可使用一个 Memento来捕获一个迭代的状态。迭代器在其内部存储Memento。

1 0
原创粉丝点击