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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值