设计模式之迭代器模式
迭代器模式(Iterator Pattern)是一种行为设计模式,用于提供一种按着某种方式访问聚合对象中元素的方法,而不暴露该聚合对象底层实现。通过迭代器模式,客户端可以以统一的方式遍历不同集合(如数组、链表等),无需关心集合的内部表示。
适用场景
- 简化复杂数据结构的访问
客户端只关系元素的遍历,不需要了解复杂的集合实现,将针对集合元素的遍历逻辑与集合的具体实现解耦。 - 提供多种遍历与访问方式
针对同一集合提供多方式(正序、逆序、跳步等)对集合中的元素进行访问。 - 集合类型的多样化
客户端以一致的方式处理不同类型的集合,而无需关心不同类型集合内部的实现。修改集合类型时,客户端中针对集合遍历的代码无需修改,符合开闭原则。
UML图
上图中各角色说明如下表:
角色 | 功能说明 |
---|---|
迭代器接口:Iterator | 迭代器约束,定义了需要实现的遍历方式。 |
迭代器实现:ConcreteIterator | 对迭代器定义的遍历方式的具体实现,需要感知聚合类的内部具体实现。 |
聚合接口:IAggregate | 定义了产生迭代器角色的接口,根据业务需要返回不同的迭代器。 |
聚合实现:ConcretdAggregate | 负责实现聚合接口约束,创建具体的迭代器实例。同时可以根据业务需要返回不同类型的迭代器实例。 |
客户端:client | 使用聚合与迭代器完成业务需要的遍历逻辑。 |
迭代器模式的关键在于实现Iterator与IAggregate中的关键方法:
- Iterator接口:
- boolean hasNext():用于判断是否还有下一个元素。
- E next():获取下一个元素。
- IAggregate接口:
- Iterator createIterator():创建一个迭代器对象。
实例分析
在java的集合框架JUC中,很多集合类(如ArrayList、LinkedList、HashSet等)都提供了iterator方法,用于返回Iterator实例。下面以ArrayList源码进行分析。
实例UML图
代码实现
在ArrayList的整个继承链中,通过最顶层的Iterable接口进行了约束。该接口中定义了iterator方法,用于返回Iterator实例。Collection接口通过对Iterable进行继承,实现对所有集合类的约束。Iterable接口定义如下:
1 | public interface Iterable<T> { |
为了避免Collection接口在后续迭代的过程,影响到List相关接口对于Iterator的约束,因此List接口中同样定义了iterator方法,用于产生Itrator实例。同时为了实现针对List个性化的遍历需求,定义了ListIterator,实现了向前遍历的功能,同时增加了set与add相关方法。ListIterator接口仅适用于List类型的约束,如ArrayList、LinkedList等。ListIterator定义如下:
1 | public interface ListIterator<E> extends Iterator<E> { |
由于每一种具体的List类型的内部集合实现均不同,比如ArrayList内部使用数组,LinkedList内部使用链表。因此针对List的每一种具体类型,在其内部均定义了Iterator与ListIterator的具体实现。如Itr与ListItr实例的定义。业务在使用的List进行遍历时,面相接口编程,无需关系底层具体的迭代器实现逻辑。进行List类型的替换,也不会影响到业务遍历的逻辑。这也就是为什么迭代器模式实现复杂,还要引入该模式的原因。
1 | public void iterateVerify() { |
本文标题:设计模式之迭代器模式
文章作者:EricZhang
发布时间:2024-12-16
最后更新:2024-12-20
原始链接:https://techcoffe.com/2024/12/16/Design-Pattern-of-Iterator/
版权声明:本博客中所有原创文章,除特别声明外,均采用 Creative Commons BY-NC-SA 4.0 国际许可协议 进行授权。转载请注明出处!非原创内容的版权归原作者所有,如有侵权请及时联系删除。