迭代这个词不陌生,List,Set,Map等等都有迭代器。所谓的迭代器就是访问该聚合对象中的各个元素。比如链表遍历。如果将该链表的创建和遍历都放在一个类中那肯定是不行的,如果要更改遍历方法就得修改源码,这违反了开闭原则。如果类不提供遍历方法,由用户自己实现也是不可以的,因为这样会暴露聚合类的内部表示,对数据是不安全的,所以可以在客户端和聚合类之间放置一个迭代器,客户只需要调用迭代器就可以完成聚合类数据的遍历,任何的遍历都交给迭代器来操作,可以在迭代器内定义许多不同的遍历方法。

一个迭代器模式有4个具体角色 抽象聚合,具体聚合,抽象迭代器,具体迭代器。聚合类符合添加,删除聚合对象以及创建迭代器。迭代器依赖于聚合,定义访问和遍历聚合元素的方法。

抽象聚合

public interface DiyList {
    void add(Object o);
    void remove(Object o);
    DiyIrerator getDiyIrerator();
}

具体聚合

public class DiyListImpl implements DiyList {
  private  ArrayList<Object> Objects=new ArrayList<>();

    @Override
    public void add(Object o) {
Objects.add(o);
    }

    @Override
    public void remove(Object o) {
Objects.remove(o);
    }

    @Override
    public DiyIrerator getDiyIrerator() {
        return (new ConcreteIterator(Objects) );
    }
}

抽象迭代器

public interface DiyIrerator {
    Object first();
    Object next();
    boolean hasNext();
}

具体迭代器

public class ConcreteIterator implements DiyIrerator {
    private ArrayList<Object> list=null;
   int index=-1;
    public ConcreteIterator(ArrayList<Object> list) {
        this.list = list;
    }


    @Override
    public Object first() {
        return list.get(index+1);
    }

    @Override
    public Object next() {
        Object o=null;
        if(hasNext()){
            return list.get(++index);
        }
        return null;
    }

    @Override
    public boolean hasNext() {
        if(list.get(index+1)!=null){
            return true;
        }
        return false;
    }
}

测试类

public class Client {
    public static void main(String[] args) {
        DiyListImpl diyList = new DiyListImpl();
        diyList.add("1");
        diyList.add("2");
        diyList.add("3");
        DiyIrerator diyIrerator = diyList.getDiyIrerator();
        String first = (String) diyIrerator.first();
        System.out.println(first);
    }
}

可以看到,每一个聚合类绑定一个固定的迭代器,对用户来说聚合类内部是未知的,对聚合类来说,迭代方法没有与自己绑定,完全符合开闭原则。修改聚合类的遍历方法只需要修改对应的迭代器类。

应用场景:当需要为聚合对象提供多种可能会更改的遍历方式时,或者需要保护聚合类内部细节时

posted on 2020-04-28 16:40  Vinlen  阅读(132)  评论(0编辑  收藏  举报