• 简说设计模式——迭代器模式


    一、什么是迭代器模式

      迭代器这个词在Java中出现过,即Java中使用Iterator迭代器对集合进行遍历,但迭代器模式算是一个没落的模式,基本上没人会单独写一个迭代器,除非是产品性质的开发。

      迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。UML结构图如下:

      其中,Aggregate是聚集抽象类,负责提供创建具体迭代器角色的接口;Iterator是迭代抽象类,用于定义得到开始对象、得到下一个对象、判断是否到结尾、当前对象等抽象方法,统一接口;ConcreteAggregate是具体聚集类,继承Aggregate;ConcreteIterator是具体迭代器类,继承Iterator,实现开始、下一个、是否结尾、当前对象等方法。

      1. 抽象容器

      负责提供接口,比如存在一个类似createIterator()这样的方法,在Java中一般是iterator()方法。

    1 public interface Aggregate {
    2     
    3     public void add(Object object);
    4     
    5     public void remove(Object object);
    6     
    7     public Iterator iterator();
    8 
    9 }

      2. 抽象迭代器

      负责定义访问和遍历元素的接口,基本上有固定的三个方法,即first()获取第一个元素、next()访问下一个元素、hasNext()是否已经遍历到底部。

    1 public interface Iterator {
    2     
    3     public Object next();    //遍历到下一个元素
    4     
    5     public boolean hasNext();    //是否已经遍历到尾部
    6     
    7     public boolean remove();    //删除当前指向的元素
    8 
    9 }

      3. 具体容器

     1 public class ConcreteAggregate implements Aggregate {
     2     
     3     private Vector vector = new Vector();
     4 
     5     @Override
     6     public void add(Object object) {
     7         this.vector.add(object);
     8     }
     9 
    10     public void remove(Object object) {
    11         this.remove(object);
    12     }
    13 
    14     @Override
    15     public Iterator iterator() {
    16         return new ConcreteIterator(this.vector);
    17     }
    18     
    19 }

      4. 具体迭代器

      简单的实现就是通过一个游标,在一个容器中上下翻滚,遍历所有它需要查看的元素。

     1 public class ConcreteIterator implements Iterator {
     2     
     3     private Vector vector = new Vector();
     4     public int cursor = 0;    //定义当前游标
     5     
     6     public ConcreteIterator(Vector vector) {
     7         this.vector = vector;
     8     }
     9 
    10     @Override
    11     public Object next() {
    12         Object result = null;
    13         
    14         if (this.hasNext()) {
    15             result = this.vector.get(this.cursor ++);
    16         } else {
    17             result = null;
    18         }
    19         
    20         return result;
    21     }
    22 
    23     @Override
    24     public boolean hasNext() {
    25         if (this.cursor == this.vector.size()) {
    26             return false;
    27         }
    28         
    29         return true;
    30     }
    31 
    32     @Override
    33     public boolean remove() {
    34         this.vector.remove(this.cursor);
    35         
    36         return true;
    37     }
    38 
    39 }

      5. Client客户端

      下面测试一下,注意引入自定义的Iterator类,而不是Java封装好的Iterator类。

     1 public class Client {
     2     
     3     public static void main(String[] args) {
     4         Aggregate aggregate = new ConcreteAggregate();
     5         aggregate.add("abc");
     6         aggregate.add("aaa");
     7         aggregate.add("1234");
     8         
     9         //遍历
    10         Iterator iterator = aggregate.iterator();
    11         while (iterator.hasNext()) {
    12             System.out.println(iterator.next());
    13         }
    14     }
    15 
    16 }

      运行结果如下:

      

    二、迭代器模式的应用

      1. 何时使用

    • 遍历一个聚合对象时

      2. 方法

    • 把在元素间游走的责任交给迭代器,而不是聚合对象

      3. 优点

    • 支持以不同的方式遍历一个聚合对象
    • 迭代器简化了聚合类
    • 在同一个聚合上可以有多个遍历
    • 增加新的聚合类和迭代器类都很方便,无需修改原有代码

      4. 缺点

    • 增加了系统的复杂性。因为迭代器模式将存储数据和遍历数据的职责分离,增加了新的聚合类需要对应增加新的迭代器类,增加了系统的复杂性。

      5. 使用场景 

    • 访问一个聚合对象的内容无需暴露它的内部表示时
    • 需要为聚合对象提供多种便利方式时
    • 为遍历不同的聚合结构提供一个统一的接口

      6. 应用实例

    • Java中的Iterator迭代器
    • foreach遍历

    三、迭代器模式的实现

      这部分内容就不再赘述了,具体实现与上方代码没有太大区别,根据具体应用场景加以改变即可,当然也可以参考java.util.Iterator的源码。


      到此,常见的23种设计模式就介绍完了,所有源码皆已上传至码云,至于扩展的新模式(常用23个设计模式之外的设计模式),后续有机会会继续更新,短时间内不再编写有关设计模式的内容。

      源码地址:https://gitee.com/adamjiangwh/GoF 

  • 相关阅读:
    关于idea中启动clean时Process terminated报错
    关于idea启动jsp时候Please, configure Web Facet first!
    关于Javaweb中jstl的foreach不能显示数据的问题
    关于Javaweb中报错信息Cause: java.sql.SQLException: Unknown initial character set index '255' received from server.解决办法
    关于使用idea 进行druid的数据库连接报错解决Cannot resolve com.mysq.jdbc.Connection.ping method. Will use 'SELECT 1' instead
    关于c3p0中显示数据库连接超时处理方法
    havel定理
    Skier
    扩展欧几里德算法(待补充)
    next_permutation(全排列)
  • 原文地址:https://www.cnblogs.com/adamjwh/p/11024311.html
Copyright © 2020-2023  润新知