当前位置: 首页 > article >正文

设计模式 16 迭代器模式

设计模式 16

  • 创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
  • 结构型模式(7):适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式
  • 行为型模式(11):责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

文章目录

  • 设计模式 16
    • 迭代器模式(Iterator Pattern)
      • 1 定义
      • 2 结构
      • 3 示例代码
      • 6 特点
      • 7 适用场景
      • 8 总结

迭代器模式(Iterator Pattern)

1 定义

迭代器模式的核心思想是提供一种统一的接口来遍历聚合对象中的元素,而不需要了解聚合对象的内部结构。通过这种方式,集合和遍历算法之间解耦,遍历的方式可以更容易地改变或扩展。

2 结构

迭代器模式包含以下角色:

  • 迭代器接口(Iterator): 定义访问和遍历元素的接口,通常包括 NextHasNextCurrent 等方法。
  • 具体迭代器(ConcreteIterator): 实现迭代器接口,负责具体元素的遍历。
  • 聚合接口(Aggregate): 定义创建迭代器对象的接口。
  • 具体聚合类(ConcreteAggregate): 实现聚合接口,返回具体的迭代器实例。

UML 类图

+-------------------------------+       +-------------------+
|   Aggregate                   |       |     Iterator      |
+-------------------------------+       +-------------------+
| + CreateIterator(): Iterator  |       | + HasNext(): bool |
+-------------------------------+       | + Next(): T       |
        ^                               | + Current(): T    |
        |                               +-------------------+
+-------------------------------+
|ConcreteAggregate              |       +-------------------+
+-------------------------------+       | ConcreteIterator  |
| + CreateIterator(): Iterator  |       | + HasNext(): bool |
+-------------------------------+       | + Next(): T       |
                                        | + Current(): T    |
                                        +-------------------+

3 示例代码

假设我们要实现一个自定义的 List 集合,并为它提供一个迭代器来遍历其中的元素。

迭代器接口

// 迭代器接口
public interface IIterator<T>
{
    bool HasNext();
    T Next();
    T Current { get; }
}

具体迭代器

// 具体迭代器
public class ListIterator<T> : IIterator<T>
{
    private readonly List<T> _list;
    private int _position = 0;

    public ListIterator(List<T> list)
    {
        _list = list;
    }

    public bool HasNext()
    {
        return _position < _list.Count;
    }

    public T Next()
    {
        return _list[_position++];
    }

    public T Current => _list[_position];
}

聚合接口

// 聚合接口
public interface IAggregate<T>
{
    IIterator<T> CreateIterator();
}

具体聚合类

// 具体聚合类
public class CustomList<T> : IAggregate<T>
{
    private readonly List<T> _items = new List<T>();

    public void Add(T item)
    {
        _items.Add(item);
    }

    public IIterator<T> CreateIterator()
    {
        return new ListIterator<T>(_items);
    }
}

客户端代码

class Program
{
    static void Main(string[] args)
    {
        // 创建聚合对象并添加元素
        CustomList<string> list = new CustomList<string>();
        list.Add("Item 1");
        list.Add("Item 2");
        list.Add("Item 3");

        // 创建迭代器并遍历元素
        IIterator<string> iterator = list.CreateIterator();
        while (iterator.HasNext())
        {
            string item = iterator.Next();
            Console.WriteLine(item);
        }
    }
}

运行结果

Item 1
Item 2
Item 3

在这个例子中,我们创建了一个自定义的 CustomList 类,并为其提供了 ListIterator 作为具体的迭代器。ListIterator 实现了遍历列表元素的逻辑。客户端代码通过迭代器接口来遍历 CustomList 中的元素,而无需了解 CustomList 的内部结构。

6 特点

  • 优点:

    • 简化聚合类: 迭代器模式将遍历的职责从聚合类中分离出来,简化了聚合类的实现。

    • 一致的接口: 迭代器模式提供了一致的接口用于遍历不同类型的聚合对象,无需关心其内部实现。

    • 灵活性高: 可以自由更改迭代算法而不影响聚合类。

  • 缺点:

    • 开销增加: 对于非常简单的聚合类,引入迭代器模式可能会导致额外的开销和复杂性。

7 适用场景

  • 需要遍历聚合对象: 当需要遍历一个聚合对象中的元素时,可以使用迭代器模式。
  • 不同的遍历方式: 需要多种遍历方式或需要隐藏遍历的实现细节时,迭代器模式是一个合适的选择。
  • 统一的遍历接口: 当需要为不同类型的聚合对象提供统一的遍历接口时,迭代器模式非常适用。

8 总结

迭代器模式提供了一种遍历聚合对象的标准方法,通过解耦遍历逻辑和聚合对象的实现,增强了系统的灵活性和可扩展性。该模式特别适合需要在不暴露对象内部结构的情况下对对象进行遍历的场景。


http://www.kler.cn/news/283787.html

相关文章:

  • OCI编程高级篇(十四) 直接路径装载设置字段信息
  • 数据结构与算法 第四天(串、数组、广义表)
  • HTTP分析
  • 高级java每日一道面试题-2024年8月30日-数据库篇-数据库的三范式是什么?
  • Java技术栈 —— Spark入门(三)之实时视频流
  • Dubbo如何传递链路追踪id?
  • 小琳AI课堂:使用ChatGPT API搭建系统(二)
  • innovus:如何让部分sink长到target insertion delay的长度
  • 关于OBI 在unity URP环境下使用的正确步骤
  • 网络编程(学习)2024.8.27
  • jQuery基础——选择器的补充方法——过滤方法、查找方法
  • python使用multiprocessing多进程通讯
  • 各种各样的正则表达式
  • 92. UE5 RPG 使用C++创建GE实现灼烧的负面效果
  • 达梦数据库-DM8 企业版安装指南
  • [java][代码] java中date格式化输出时间字符串
  • 《征服数据结构》LFU缓存
  • Vatee万腾平台:打造企业智能化转型的坚实后盾
  • 【Android】UIMode
  • fpga图像处理实战-双三次插值算法
  • Jmeter提取token并设置为全局变量
  • 聊聊STM32 MCU的BOOT0和BOOT1引脚
  • 浅谈Vue3和React18
  • 六个方面探讨企业为何迫切需要替换FTP
  • PyQt 迁移到 PySide
  • WPF ToolkitMVVM RelayCommand
  • 探究:Elasticsearch 文档的 _id 是 Lucene 的 docid 吗?
  • DNN学习平台(GoogleNet、SSD、FastRCNN、Yolov3)
  • C# 自动化抢购脚本:基于商品链接的实现方案
  • 【杂谈】新能源和智能车