【设计模式】第十六章:迭代器模式详解及应用案例

系列文章

【设计模式】七大设计原则
【设计模式】第一章:单例模式
【设计模式】第二章:工厂模式
【设计模式】第三章:建造者模式
【设计模式】第四章:原型模式
【设计模式】第五章:适配器模式
【设计模式】第六章:装饰器模式
【设计模式】第七章:代理模式
【设计模式】第八章:桥接模式
【设计模式】第九章:外观模式 / 门面模式
【设计模式】第十章:组合模式
【设计模式】第十一章:享元模式
【设计模式】第十二章:观察者模式
【设计模式】第十三章:模板方法模式
【设计模式】第十四章:策略模式
【设计模式】第十五章:责任链模式
【设计模式】第十六章:迭代器模式
【设计模式】第十七章:状态模式
【设计模式】第十八章:备忘录模式
【设计模式】第十九章:访问者模式
【设计模式】第二十章:解释器模式
【设计模式】第二十一章:命令模式
【设计模式】第二十二章:中介者模式


文章目录

  • 系列文章
  • 一、定义
  • 二、角色分类
  • 三、实现方式
    • UML图
    • 具体实现
  • 四、应用场景
  • 五、优缺点
    • 优点
    • 缺点
  • 推荐


一、定义

摘自百度百科: 提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。


二、角色分类

抽象迭代器(Iterator)

定义了访问和遍历元素的接口,声明了用于遍历数据元素的方法

具体迭代器(Concrete Iterator)

实现了抽象迭代器,完成遍历数据元素的具体实现方法,同时在迭代器中通过游标来记录在聚合对象中当前的所处位置,游标通常是一个非负整数

抽象聚合类(Aggregate)

用于存储和管理元素对象,声明了创建迭代器对象的方法,充当抽象迭代器工厂使用

具体聚合类(Concrete Aggregate)

实现了抽象聚合类中声明的创建迭代器对象的方法,该方法返回一个于该具体聚合类对应的具体迭代器实例

客户角色(Client)

具体调用方法的角色


三、实现方式

UML图

【设计模式】第十六章:迭代器模式详解及应用案例_第1张图片

具体实现

假如我们有一个场景为:医院看病时需要挂号,按照挂号号码来看病,就可以使用迭代器模式实现

/**
 * 病号实体类
 */
@Data
@ToString
public class Patient {

  /**
   * 病人姓名
   */
  private String name;

  /**
   * 挂号号码
   */
  private Integer number;

  public Patient(String name, Integer number) {
    this.name = name;
    this.number = number;
  }

  public void diagnosis() {
    System.out.println("医生你好,我是第" + this.number + "号病人" + this.name)
  }
}

抽象聚合类(Aggregate)

public interface Aggregate {
  
  void addPatient(Patient patient);

  void removePatient(Patient patient);

  PatientIterator createPatientIterator();
}

具体聚合类(Concrete Aggregate)

public class ConcreteAggregate implements Aggregate {
  // 病人列表
  private List<Patient> list;

  public ConcreteAggregate() {
    this.list = new ArrayList<>();
  }

  @Override
  public void addPatient(Patient patient) {
    this.list.add(patient);
  }

  @Override
  public void removePatient(Patient patient) {
    this,list.remove(patient);
  }

  @Override
  public PatientIterator createPatientIterator() {
    return new ConcreteIterator(this.list);
  }
}

抽象迭代器(Iterator)

public interface Iterator {
  boolean hasNext();

  Patient next();
}

具体迭代器(Concrete Iterator)

public class ConcreteIterator implements Iterator {
  private List<Patient> list;
  private int position = 0;
  private Patient currentPatient;

  public ConcreteIterator(List<Patient> list) {
    this.list = list;
  }

  @Override
  public boolean hasNext() {
    return position < list.size;
  }

  @Override
  public Patient next(){
    currentPatient = list.get(position);
    position++;
    return currentPatient;
  }
}

客户角色(Client)

public class Client {
  public static void main(String[] args) {
    Aggregate doctorA = new ConcreteAggregate();
    doctorA.addPatient(new Patient("张三", 1));
    doctorA.addPatient(new Patient("李四", 2));
    doctorA.addPatient(new Patient("王五", 3));
    doctorA.addPatient(new Patient("赵六", 4));

    Iterator iterator = doctorA.createPatientIterator();
    while (iterator.hasNext()) {
      Patient patient = iterator.next();
      patient.diagnosis();
    }
  }
}

运行结果

医生你好,我是第1号病人张三
医生你好,我是第2号病人李四
医生你好,我是第3号病人王五
医生你好,我是第4号病人赵六

四、应用场景

以下部分内容摘自菜鸟教程

意图: 提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。

主要解决: 不同的方式来遍历整个整合对象。

何时使用: 遍历一个聚合对象。

如何解决: 把在元素之间游走的责任交给迭代器,而不是聚合对象。

关键代码: 定义接口:hasNext, next。

应用实例: JAVA 中的 iterator。

使用场景:

  1. 访问一个聚合对象的内容而无须暴露它的内部表示。
  2. 需要为聚合对象提供多种遍历方式。
  3. 为遍历不同的聚合结构提供一个统一的接口。

注意事项: 迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。


五、优缺点

优点

  1. 它支持以不同的方式遍历一个聚合对象。
  2. 迭代器简化了聚合类。
  3. 在同一个聚合上可以有多个遍历。
  4. 在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。

缺点

由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。


推荐

关注博客和公众号获取最新文章

Bummon’s Blog | Bummon’s Home | 公众号

你可能感兴趣的:(设计模式,设计模式,迭代器模式)