28. 迭代器模式

作者: Next_吴思成 | 来源:发表于2018-07-15 21:38 被阅读2次

    定义

    迭代器模式(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

    相关文章

      网友评论

        本文标题:28. 迭代器模式

        本文链接:https://www.haomeiwen.com/subject/qgqoyftx.html