设计模式简讲程序员

28. 迭代器模式

2018-07-15  本文已影响2人  Next_吴思成

定义

迭代器模式(Iterator Pattern):提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标(Cursor)。

通俗理解

物流运输货物的时候,有不同的装箱方式也有不同的卸货方式,例如啤酒之类玻璃瓶装的要轻拿轻放、电子产品也是需要轻拿轻放的、建筑钢材之类都就随意了,可以乱扔。这个方式可不能搞混了,如果啤酒采用乱扔的方式,那么运输的就不是啤酒,而是一堆玻璃渣子;如果建筑钢材还轻拿轻放,那就太浪费人力物力。

面对这种情况,我们只能谨慎,不然这这一趟运输就白跑喽。可是要做到谨慎可不是那么容易的,因为不同的货物有不同的卸货方式,而不同的卸货方式需要不同的工具,那么我们在运输的时候就需要把相应的卸货工具给带上,况且,还需要有人会用这些卸货工具,如果一个人连叉车都没用过,那么怎么可以让他开呢?

于是,又陷进了一个,增加成本的困境。

解决这种困境的方式,有一个,就是成立专门的装卸货部门。由这个部门专业进行装卸货的工作,他们有专业的工具也有专业的人,物流公司只需要把货物给运到,剩下的工作就交个装卸货部门就可以了。他们会把货物妥妥当当地放到该放到的地方上去。

迭代器模式就是这样的一个理念。装卸货和运输分割开来,运输就只管运输,而装卸货也就只是装卸货。表现在程序上,就是对象在容器存储和对象的获取分割开来,在对象的获取方面,不管底层采用怎么样的存储方式,获取的方式都是采用统一接口,不关心底层的实现是如何。就是说,不管是怎么的货物,怎么摆放到车厢当中,只要交给卸货部门,就能很好卸货。

示例

业务采用装上面的实例。

渣渣程序

数组

public class Array {
    public String[] goods = new String[10];
}

程序入口

public class Main {
    public static void main(String[] args) {
        Array array = new Array();
        array.goods[0] = "第一个货物";
        array.goods[1] = "第二个货物";
        array.goods[2] = "第三个货物";

        System.out.println(array.goods[0]);
        System.out.println(array.goods[1]);
        System.out.println(array.goods[2]);
    }
}
//第一个货物
//第二个货物
//第三个货物

上面程序的问题显而易见了,就是我们必须知道对象在底层的实现方式,然后我们才能够根据他的实现方式去读取他里面的内容,这是一个数组的实现,我们采用数组的读取方式,那如果是链表的实现,那么我们也得采用链表的读取方式,太浪费精力。

优化

类图

程序

Array类不变。

迭代器接口与实现

public interface Iterator {
    String first();
    String next();
    boolean hasNext();
}
public class ConcreteIterator implements Iterator {
    private Array array;
    private int cursor;
    public ConcreteIterator(Array array) {
        cursor = 0;
        this.array = array;
    }
    public String first() {
        cursor = 0;
        return array.goods[cursor];
    }
    public String next() {
        String currentItem = array.goods[cursor];
        cursor ++;
        return currentItem;
    }
    public boolean hasNext() {
        if(array.goods[cursor] != null) {
            return true;
        }
        return false;
    }
}

程序入口

public class Main {
    public static void main(String[] args) {
        Array array = new Array();
        array.goods[0] = "第一个货物";
        array.goods[1] = "第二个货物";
        array.goods[2] = "第三个货物";

        Iterator iterator = new ConcreteIterator(array);
        while(iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
//第一个货物
//第二个货物
//第三个货物

优点

  1. 支持不同的迭代方法去访问一个容器对象;
  2. 简化聚合类,容器不需要提供遍历数据的方法,简化聚合类的设计;
  3. 存储和遍历分开,有利于解耦合。

缺点

  1. 存储和遍历分开,新加一个存储类就得增加一个迭代器的类,造成类的膨胀;
  2. 开发难度大,要考虑好扩展性。

应用场景

  1. 遍历容器内的对象,并不需要知道容器内部的数据结构;
  2. 允许对容器进行多级遍历;
  3. 提供一致的接口来遍历不同的实现方式的容器。

实例

JDK的java.util包,Java原生支持,foreach循环就是通过这个实现的。

程序

e28_iterator_pattern

吐槽

就是提供统一接口来访问一个容器对象而已。

https://www.jianshu.com/p/d70e15d140a5

上一篇 下一篇

猜你喜欢

热点阅读