Design Patterns(十七):Iterator Pattern--VB代码
★★★★★
提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
结构图

角色
- 迭代器(Iterator)角色:负责定义和遍历元素的接口。
- 具体迭代器(Concrete Iterator)角色:实现迭代器接口,并要记录遍历中的当前位置。
- 容器(Container)角色:容器角色负责提供创建具体迭代器角色的接口。
- 具体容器(Concrete Container)角色:具体容器角色实现创建具体迭代器角色的接口——这个具体迭代器角色于该容器的结构相关。
动机
在软件构建过程中集合对象内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部程序代码透明的访问其中包含的元素; 同时这种“透明遍历”也为“同一种算法在多种集合对象上进行操作” 提供了可能。
使用面向对象技术将这种遍历机制抽象抽象为“迭代器”为“应对变化中的集合对象”提供了一种优雅的方式。
意图
提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
示意性代码


Module MainApp
Sub Main()
Dim a As New ConcreteAggregate
a(0) = "Item A"
a(1) = "Item B"
a(2) = "Item C"
a(3) = "Item D"
'Create Iterator and provide aggregate
Dim i As New ConcreteIterator(a)
Console.WriteLine("Iterating over collection -----")
Dim item As Object = i.First()
While item IsNot Nothing
Console.WriteLine(item)
item = i.Next()
End While
'Wait for user
Console.Read()
End Sub
End Module
'"Aggregate"
Public MustInherit Class Aggregate
Public MustOverride Function CreateIterator() As Iterator
End Class
'"ConcreteAggregate"
Public Class ConcreteAggregate
Inherits Aggregate
Private items As New ArrayList
Public Overrides Function CreateIterator() As Iterator
Return New ConcreteIterator(Me)
End Function
'Property
Public ReadOnly Property Count() As Integer
Get
Return items.Count
End Get
End Property
'Indexer
Default Public Property Item(ByVal Index As Integer) As Object
Get
Return items(Index)
End Get
Set(ByVal value As Object)
items.Insert(Index, value)
End Set
End Property
End Class
'"Iterator"
Public MustInherit Class Iterator
Public MustOverride Function First() As Object
Public MustOverride Function [Next]() As Object
Public MustOverride Function IsDone() As Boolean
Public MustOverride Function CurrentItem() As Object
End Class
'"ConcreteIterator"
Public Class ConcreteIterator
Inherits Iterator
Private aggregate As ConcreteAggregate
Private current As Integer = 0
'Constructor
Public Sub New(ByVal aggregate As ConcreteAggregate)
Me.aggregate = aggregate
End Sub
Public Overrides Function First() As Object
Return aggregate(0)
End Function
Public Overrides Function [Next]() As Object
Dim ret As Object = Nothing
If current < aggregate.Count - 1 Then
ret = aggregate(System.Threading.Interlocked.Increment(current))
End If
Return ret
End Function
Public Overrides Function CurrentItem() As Object
Return aggregate(current)
End Function
Public Overrides Function IsDone() As Boolean
Return current >= aggregate.Count
End Function
End Class
一个实例
下面的迭代器代码用来演示跳过某些项目遍历一个集合。


' MainApp test application
Module MainApp
Sub Main()
' Build a collection
Dim collection As New Collection()
collection(0) = New Item("Item 0")
collection(1) = New Item("Item 1")
collection(2) = New Item("Item 2")
collection(3) = New Item("Item 3")
collection(4) = New Item("Item 4")
collection(5) = New Item("Item 5")
collection(6) = New Item("Item 6")
collection(7) = New Item("Item 7")
collection(8) = New Item("Item 8")
' Create iterator
Dim iterator As New Iterator(collection)
' Skip every other item
iterator.[Step] = 2
Console.WriteLine("Iterating over collection:")
Dim item As Item = iterator.First()
While Not iterator.IsDone
Console.WriteLine(item.Name)
item = iterator.[Next]()
End While
' Wait for user
Console.Read()
End Sub
End Module
Public Class Item
Private m_name As String
' Constructor
Public Sub New(ByVal name As String)
Me.m_name = name
End Sub
' Property
Public ReadOnly Property Name() As String
Get
Return m_name
End Get
End Property
End Class
' "Aggregate"
Public Interface IAbstractCollection
Function CreateIterator() As Iterator
End Interface
' "ConcreteAggregate"
Public Class Collection
Implements IAbstractCollection
Private items As New ArrayList()
Public Function CreateIterator() As Iterator Implements IAbstractCollection.CreateIterator
Return New Iterator(Me)
End Function
' Property
Public ReadOnly Property Count() As Integer
Get
Return items.Count
End Get
End Property
' Indexer
Default Public Property Item(ByVal index As Integer) As Object
Get
Return items(index)
End Get
Set(ByVal value As Object)
items.Add(value)
End Set
End Property
End Class
' "Iterator"
Public Interface IAbstractIterator
Function First() As Item
Function [Next]() As Item
ReadOnly Property IsDone() As Boolean
ReadOnly Property CurrentItem() As Item
End Interface
' "ConcreteIterator"
Public Class Iterator
Implements IAbstractIterator
Private collection As Collection
Private current As Integer = 0
Private m_step As Integer = 1
' Constructor
Public Sub New(ByVal collection As Collection)
Me.collection = collection
End Sub
Public Function First() As Item Implements IAbstractIterator.First
current = 0
Return TryCast(collection(current), Item)
End Function
Public Function [Next]() As Item Implements IAbstractIterator.[Next]
current += m_step
If Not IsDone Then
Return TryCast(collection(current), Item)
Else
Return Nothing
End If
End Function
' Properties
Public Property [Step]() As Integer
Get
Return m_step
End Get
Set(ByVal value As Integer)
m_step = value
End Set
End Property
Public ReadOnly Property CurrentItem() As Item Implements IAbstractIterator.CurrentItem
Get
Return TryCast(collection(current), Item)
End Get
End Property
Public ReadOnly Property IsDone() As Boolean Implements IAbstractIterator.IsDone
Get
Return current >= collection.Count
End Get
End Property
End Class
Iterator Pattern模式的几个要点:
1、迭代抽象:访问一个聚合对象的内容而无需暴露它的内部信息。
2、迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。
3、迭代器健壮性考虑:遍历的同时更改迭代器所在的集合结构,会导致问题。
我的理解
封装集合对象的内部结构和遍历集合的算法,支持集合和算法的变化。
参考资料
《C#面向对象设计模式纵横谈系列课程(18)》 李建中老师
分类:
Design Pattern
随笔分类 (333)
Cnblogs's
Front End
Oracle's
Software's
- Apache HTTP Server
- CodeSmith Community
- Grapecity(FAQ)
- Mybase
- ClubFarPoint(Forum)
- Beyond Compare
- CrystalReport(FAQ)
- 秀丸
- Software Advice
- Software: Business & Nonprofit | Reviews and Top Software at Capterra
- Capterra
- Business Software Reviews from Software Advice
Copyright © 2025 sekihin
Powered by .NET 9.0 on Kubernetes
Powered by .NET 9.0 on Kubernetes
![]() | 本作品采用 知识共享署名-非商业性使用 2.5 中国大陆许可协议进行许可。 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通