おーみんブログ

C#, ASP.NET Core, Unityが大好きです。

VB.NETでIteratorパターンを体験してみた。

はじめに

GoFデザインパターンの1つであるIteratorパターンを体験してみました。

Iteratorパターンとは

通常配列やリストのループ処理をする際はfor文を用いますが、配列の要素に対してどのような順番でアクセスしていくか(走査方法)を提供するデザインパターンIteratorパターンと言います。

Iteratorパターンを形成するためのクラス図は以下のようになります。)

ja.wikipedia.org

サンプルコード

以下にサンプルコード(サンプルコードはデザインパターンの超名著『Java言語で学ぶ デザインパターン入門 第3版』(結城 浩)を参考にさせていただきました。)を記載します。

こちらのサンプルではIteratorパターンを用いて買い物かごに入れたものを順番に取り出しています。

Module Program
    Sub Main()
        Dim basket As New Basket(4)
        basket.AppendItem(New Item("あさり"))
        basket.AppendItem(New Item("いちご"))
        basket.AppendItem(New Item("ウーロン茶"))
        basket.AppendItem(New Item("エビ"))

        Dim iterator As IIterator(Of Item) = basket.Iterator()
        While iterator.HasNext
            Dim item As Item = iterator.NextElement
            Console.WriteLine(item.GetItemName)
        End While
    End Sub
End Module

'Aggregate
Public Interface IIterable(Of T)
    Function Iterator() As IIterator(Of T)
End Interface

'Iterator
Public Interface IIterator(Of T)
    Function HasNext() As Boolean
    Function NextElement() As T
End Interface

Public Class Item
    Private _itemName As String

    Public Sub New(itemName As String)
        _itemName = itemName
    End Sub

    Public Function GetItemName() As String
        Return _itemName
    End Function
End Class

'Concrete Aggregate
Public Class Basket
    Implements IIterable(Of Item)

    Private _item() As Item
    Private _last As Integer = 0

    Public Sub New(maxSize As Integer)
        _item = New Item(maxSize) {}
    End Sub

    Public Function GetItemAt(index As Integer) As Item
        Return _item(index)
    End Function

    Public Sub AppendItem(item As Item)
        _item(_last) = item
        _last += 1
    End Sub

    Public Function GetLength() As Integer
        Return _last
    End Function

    Public Function Iterator() As IIterator(Of Item) Implements IIterable(Of Item).Iterator
        Return New BasketIterator(Me)
    End Function
End Class

'Concrete Iterator
Public Class BasketIterator
    Implements IIterator(Of Item)

    Private _basket As Basket
    Private _index As Integer = 0

    Public Sub New(basket As Basket)
        _basket = basket
    End Sub

    Public Function HasNext() As Boolean Implements IIterator(Of Item).HasNext
        If _index < _basket.GetLength Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Function NextElement() As Item Implements IIterator(Of Item).NextElement
        If Not HasNext() Then
            Throw New InvalidOperationException()
        End If

        Dim item As Item = _basket.GetItemAt(_index)
        _index += 1
        Return item
    End Function
End Class
あさり
いちご
ウーロン茶
エビ

おわりに

今となっては.NETにはIEnumerableIEnumeratorが言語仕様として組み込まれているため、今回みたく1から作る機会はそうそうないかもしれませんが、オブジェクト指向への理解を深めるという意味では学んで良かった気がします。 また他のデザインパターンも学んでいこうと思います!