详解设计模式:迭代器模式
创始人
2024-03-15 12:54:59
0

迭代器模式(Iterator Pattern)也被称为游标模式(Cursor Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。是一种最简单也最常见的设计模式。

迭代器模式 可以让用户透过特定的接口巡访容器中的每一个元素而不用了解底层的实现。

本篇文章内容包括:关于迭代器模式、观察者模式 Demo、模版方法模式的应用(ArrayList/Iterator 中的迭代器模式)


文章目录

    • 一、关于迭代器模式
        • 1、关于迭代器模式
        • 2、关于迭代器模式的构成
        • 3、关于迭代器模式的XML
        • 4、关于迭代器模式的适用场景
        • 5、关于迭代器模式的优缺点
    • 二、观察者模式 Demo
        • 1、Demo 设计
        • 2、Demo 实现
        • 3、Demo 测试
    • 三、模版方法模式的应用(ArrayList/Iterator 中的迭代器模式)


一、关于迭代器模式

1、关于迭代器模式

迭代器模式(Iterator Pattern)也被称为游标模式(Cursor Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。是一种最简单也最常见的设计模式。

迭代器模式 可以让用户透过特定的接口巡访容器中的每一个元素而不用了解底层的实现。

迭代器模式 提供一种方法顺序访问一个聚合(指一组对象的组合结构,如:Java中的集合、数组等)对象中各个元素,而又不需暴露该对象的内部表示。迭代器模式的本质:控制访问聚合对象中的元素。其设计意图:无须暴露聚合对象的内部实现,就能够访问到聚合对象中的各个元素。

2、关于迭代器模式的构成

迭代器模式主要包含以下 4 种角色:

  • 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合元素以及创建迭代器对象的接口。

  • 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。

  • 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、next() 等方法。

  • 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

3、关于迭代器模式的XML

image-20221203180812127

4、关于迭代器模式的适用场景

  • 内容保密 : 访问 集合对象 的内容 , 无需暴露内部表示 ;
  • 统一接口 : 为遍历 不同的 集合结构 , 提供统一接口。

5、关于迭代器模式的优缺点

迭代器模式优点

  • 分离了集合对象的遍历行为;
  • 抽象出了迭代器负责集合对象的遍历 , 可以让外部的代码透明的访问集合内部的数据 ;

迭代器模式缺点

  • 类的个数成对增加;
  • 迭代器模式,将存储数据 , 遍历数据两个职责拆分 ;
  • 如果新添加一个 集合类 , 需要增加该 集合类 对应的 迭代器类 , 类的个数成对增加 , 在一定程度上 , 增加了系统复杂性 ;

二、观察者模式 Demo

1、Demo 设计

定义一个可以存储学生对象的容器对象,将遍历该容器的功能交由迭代器实现。

Demo 类图如下:

在这里插入图片描述

2、Demo 实现

# Student 元素类

public class Student {private String name;private String number;@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", number='" + number + '\'' +'}';}/*** 建造者类构造函数** @param builder Builder*/private Student(Builder builder) {name = builder.name;number = builder.number;}/*** 建造者类*/public static final class Builder {private String name;private String number;public Builder() {}public Builder name(String val) {name = val;return this;}public Builder number(String val) {number = val;return this;}public Student build() {return new Student(this);}}
}

# StudentAggregate 抽象聚合(Aggregate)角色

public interface StudentAggregate {/*** 添加元素* @param student Student*/void addStudent(Student student);/*** 删除元素* @param student Student*/void removeStudent(Student student);/*** 获取迭代器对象* @return StudentIterator*/StudentIterator getStudentIterator();
}

# StudentAggregateImpl 具体聚合(ConcreteAggregate)角色

import java.util.ArrayList;
import java.util.List;public class StudentAggregateImpl implements StudentAggregate {/*** 学生列表*/private final List list = new ArrayList();@Overridepublic void addStudent(Student student) {this.list.add(student);}@Overridepublic void removeStudent(Student student) {this.list.remove(student);}@Overridepublic StudentIterator getStudentIterator() {return new StudentIteratorImpl(list);}}

# StudentIterator 抽象迭代器(Iterator)角色

public interface StudentIterator {/*** 判断是否还有下一个元素* @return boolean*/boolean hasNext();/*** 获取下一个元素* @return Student*/Student next();
}

# StudentIteratorImpl 具体迭代器(Concretelterator)角色

import java.util.List;public class StudentIteratorImpl implements StudentIterator {private final List list;private int position = 0;public StudentIteratorImpl(List list) {this.list = list;}@Overridepublic boolean hasNext() {return position < list.size();}@Overridepublic Student next() {Student currentStudent = list.get(position);position ++;return currentStudent;}
}

3、Demo 测试

public class Client {public static void main(String[] args) {// 抽象聚合类-StudentAggregate 具体聚合类-StudentAggregateImplStudentAggregate studentAggregate = new StudentAggregateImpl();// 建造者模式构造元素studentAggregate.addStudent(new Student.Builder().name("小明").number("1001").build());studentAggregate.addStudent(new Student.Builder().name("小红").number("1002").build());// 通过 具体聚合类 获取 具体迭代器StudentIterator iterator = studentAggregate.getStudentIterator();// 迭代器遍历while (iterator.hasNext()){System.out.println(iterator.next().toString());}}
}

三、模版方法模式的应用(ArrayList/Iterator 中的迭代器模式)

Java 代码中关于 List 的迭代器使用:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class IteratorDemo {public static void main(String[] args) {List list = new ArrayList<>();list.add("AA");list.add("BB");list.add("CC");// list.iterator() 方法返回的肯定是 Iterator 接口的子实现类对象Iterator iterator = list.iterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}
}

其中,List-抽象聚合类、ArrayList-具体的聚合类、Iterator-抽象迭代器、list.iterator() 返回的是实现了 Iterator 接口的具体迭代器对象。

# ArrayList 的源码对于迭代器部分的实现:

public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, Serializable {public Iterator iterator() {return new ArrayList.Itr();}private class Itr implements Iterator {// 下一个要返回元素的索引int cursor;       // 上一个返回元素的索引int lastRet = -1; int expectedModCount = modCount;Itr() {}//判断是否还有元素public boolean hasNext() {return cursor != size;}//获取下一个元素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];}...}
}

可以看到:在 iterator 方法中返回了一个实例化的 Iterator 对象。Itr 是一个内部类,它实现了 Iterator 接口并重写了其中的抽象方法。

// List 集成自 Collection
public interface List extends Collection// Collection 继承自 Iterable
public interface Collection extends Iterable

Ps:当我们在使用 Java 开发的时候,想使用迭代器模式的话,只要让我们自己定义的容器类实现 java.util.Iterable 并实现其中的 iterator() 方法使其返回一个 java.util.Iterator 的实现类就可以了。

相关内容

热门资讯

汽车油箱结构是什么(汽车油箱结... 本篇文章极速百科给大家谈谈汽车油箱结构是什么,以及汽车油箱结构原理图解对应的知识点,希望对各位有所帮...
美国2年期国债收益率上涨15个... 原标题:美国2年期国债收益率上涨15个基点 美国2年期国债收益率上涨15个基...
嵌入式 ADC使用手册完整版 ... 嵌入式 ADC使用手册完整版 (188977万字)💜&#...
重大消息战皇大厅开挂是真的吗... 您好:战皇大厅这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...
盘点十款牵手跑胡子为什么一直... 您好:牵手跑胡子这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游...
senator香烟多少一盒(s... 今天给各位分享senator香烟多少一盒的知识,其中也会对sevebstars香烟进行解释,如果能碰...
终于懂了新荣耀斗牛真的有挂吗... 您好:新荣耀斗牛这款游戏可以开挂,确实是有挂的,需要了解加客服微信8435338】很多玩家在这款游戏...
盘点十款明星麻将到底有没有挂... 您好:明星麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【5848499】很多玩家在这款游戏...
总结文章“新道游棋牌有透视挂吗... 您好:新道游棋牌这款游戏可以开挂,确实是有挂的,需要了解加客服微信【7682267】很多玩家在这款游...
终于懂了手机麻将到底有没有挂... 您好:手机麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...