zoukankan      html  css  js  c++  java
  • 设计模式之迭代器模式

    定义

    提供一种方法顺序访问一个聚合对象中的各个元素,而又不需暴露该对象的内部表示。如我们日常生活中的快递,不管内部是什么物品,
    都会被统一打包,我们不需要关心里面是什么,只需要按照目的地发送即可。

    结构

    • Iterator,迭代器接口,定义访问和遍历元素的方法。
    • ConcreteIterator,具体迭代器实现对象,实现对聚合对象的遍历。
    • Aggregate,聚合对象接口,定义创建迭代器对象的方法。
    • ConcreteAggregate,具体聚合对象,实现创建相应的迭代器对象。

    简单实现

    迭代器接口

    public interface Iterator {
    
      boolean hasNext();
    
      Object next();
    }
    

    具体迭代器

    public class ConcreteIterator implements Iterator {
    
      private ConcreteAggreate aggreate;
      private int cursor = 0;
    
      public ConcreteIterator(ConcreteAggreate aggreate) {
        this.aggreate = aggreate;
      }
    
      @Override
      public boolean hasNext() {
        return cursor < aggreate.size();
      }
    
      @Override
      public Object next() {
        return aggreate.get(cursor++);
      }
    }
    

    聚合对象接口

    public interface Aggregate {
    
      Iterator createIterator();
    }
    

    具体聚合对象的实现

    public class ConcreteAggreate implements Aggregate {
    
      private String[] data;
    
      public ConcreteAggreate(String[] data) {
        this.data = data;
      }
    
      public int size() {
        return data.length;
      }
    
      public String get(int index) {
        if (index < 0 || index >= data.length) {
          return null;
        }
        return data[index];
      }
    
      @Override
      public Iterator createIterator() {
        return new ConcreteIterator(this);
      }
    }
    

    客户端

    public class Client {
    
      public static void main(String[] args) {
        ConcreteAggreate aggreate = new ConcreteAggreate(new String[]{"a","b","c"});
        Iterator iterator = aggreate.createIterator();
        while (iterator.hasNext()) {
          System.out.println(iterator.next());
        }
      }
    
    }
    

    输出为

    a
    b
    c
    

    java中已经提供了 Iterator 接口和 Iterable 接口来实现迭代器模式。

    import java.util.Iterator;
    
    public class ConcreteIterator implements Iterator {
    
      private ConcreteAggreate aggreate;
      private int cursor = 0;
    
      public ConcreteIterator(ConcreteAggreate aggreate) {
        this.aggreate = aggreate;
      }
    
      @Override
      public boolean hasNext() {
        return cursor < aggreate.size();
      }
    
      @Override
      public Object next() {
        return aggreate.get(cursor++);
      }
    }
    

    具体聚合对象

    public class ConcreteAggreate implements Iterable {
    
      private String[] data;
    
      public ConcreteAggreate(String[] data) {
        this.data = data;
      }
    
      public int size() {
        return data.length;
      }
    
      public String get(int index) {
        if (index < 0 || index >= data.length) {
          return null;
        }
        return data[index];
      }
    
      @Override
      public java.util.Iterator iterator() {
        return new ConcreteIterator(this);
      }
    }
    

    客户端

    import java.util.Iterator;
    
    public class Client {
    
      public static void main(String[] args) {
        ConcreteAggreate aggreate = new ConcreteAggreate(new String[]{"a", "b", "c"});
        Iterator iterator = aggreate.iterator();
        while (iterator.hasNext()) {
          System.out.println(iterator.next());
        }
      }
    
    }
    

    迭代器模式在JDK的实现

    JDK中ArrayList

    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    
        public Iterator<E> iterator() {
            return new Itr();
        }
    /**
         * An optimized version of AbstractList.Itr
         */
        private class Itr implements Iterator<E> {
            int cursor;       // index of next element to return
            int lastRet = -1; // index of last element returned; -1 if no such
            int expectedModCount = modCount;
    
            // prevent creating a synthetic constructor
            Itr() {}
    
            public boolean hasNext() {
                return cursor != size;
            }
    
            @SuppressWarnings("unchecked")
            public E next() {
                checkForComodification();
                int i = cursor;
                if (i >= size)
                    throw new NoSuchElementException();
                Object[] elementData = ArrayList.this.elementData;
                if (i >= elementData.length)
                    throw new ConcurrentModificationException();
                cursor = i + 1;
                return (E) elementData[lastRet = i];
            }
        }
    }
    

    JDK中的ArrayList,LinkedList,HashSet等都实现了迭代器模式。

    总结

    优点

    1. 更好的封装性,访问一个聚合对象的内容而无需暴露该聚合对象的内部表示。
    2. 支持以不同的方式来遍历聚合对象。

    缺点

    1. 增加新的聚合类需要增加对应的迭代器类。

    本质

    迭代器模式的本质是控制访问聚合对象中的元素。

    使用场景

    1. 当我们想访问一个聚合对象的内容而又不想暴露内部表示时,可以使用迭代器模式,实际开发中我们一般使用java自身提供的迭代器实现。

    参考

    大战设计模式【12】—— 迭代器模式
    设计模式的征途—21.迭代器(Iterator)模式
    设计模式(十七)——迭代器模式(ArrayList 集合应用源码分析)
    迭代器模式(详解版)
    研磨设计模式-书籍

  • 相关阅读:
    django中的自定义标签与过滤器,静态文件配置,orm前戏
    JavaScript(js)运算符
    JavaScript(js)字面量,函数写法
    JavaScript(js)的4中输出方式
    JavaScript(js)的学习使用样式,核心语法,数据类型
    标签链接、表单及css部分知识
    学习html5 附代码
    automationOperationsWithPython
    0821 1336 模块与包的导入方法、常用模块介绍
    0816 1459 json & pickle ,目录导入,目录规范
  • 原文地址:https://www.cnblogs.com/strongmore/p/15173544.html
Copyright © 2011-2022 走看看