Composite パターン

なおこ(・∀・)さんのサイトではこちら

Composite とは「混成」といった意味ですね。

ツリー構造を表現すると面白いです。ちょっと書いてみました。
# Imports ステートメントを追加しました。


[Visual Basic]

Imports System
Imports System.Collections.Generic

' 枝と葉を同一視するためのインターフェイス
Public Interface IEntity

ReadOnly Property Name() As String

Sub Add(ByVal entity As IEntity)

ReadOnly Property HasEntity() As Boolean

ReadOnly Property EntityList() As List(Of IEntity)

End Interface


[Visual Basic]

Imports System
Imports System.Collections.Generic

' 枝クラス。
Public Class Branch
Implements IEntity


Private _name As String

Public ReadOnly Property Name() As String Implements IEntity.Name
Get
Return Me._name
End Get
End Property


Private _entityList As List(Of IEntity)

Public ReadOnly Property EntityList() As List(Of IEntity) Implements IEntity.EntityList
Get
Return Me._entityList
End Get
End Property


Public Sub New(ByVal name As String)

Me._name = name
Me._entityList = New List(Of IEntity)

End Sub


Public Sub Add(ByVal entity As IEntity) Implements IEntity.Add

Me._entityList.Add(entity)

End Sub


Public ReadOnly Property HasEntity() As Boolean Implements IEntity.HasEntity
Get
If Me._entityList.Count > 0 Then
Return True
Else
Return False
End If
End Get
End Property


End Class


[Visual Basic]

Imports System
Imports System.Collections.Generic

' 葉っぱクラス。
Public Class Leaf
Implements IEntity


Private _name As String

Public ReadOnly Property Name() As String Implements IEntity.Name
Get
Return Me._name
End Get
End Property


Public ReadOnly Property EntityList() As List(Of IEntity) Implements IEntity.EntityList
Get
Return Nothing
End Get
End Property


Public Sub New(ByVal name As String)

Me._name = name

End Sub


Public Sub Add(ByVal entity As IEntity) Implements IEntity.Add

Throw New InvalidOperationException("葉っぱからは生えないでしょ。")

End Sub


Public ReadOnly Property HasEntity() As Boolean Implements IEntity.HasEntity
Get
Return False
End Get
End Property


End Class


[Visual Basic]

Imports System
Imports System.Collections.Generic
Imports System.Windows.Forms

' 樹クラスです。
Public Class Tree


Private ReadOnly trunk As Branch


Public Sub New()

Me.trunk = New Branch("Trunk")

End Sub

' 枝葉を生やします。
Public Sub Growth()

Dim b1 As New Branch("Branch1")
Dim b2 As New Branch("Branch2")
Dim b3 As New Branch("Branch3")

Dim l1 As New Leaf("Leaf1")
Dim l2 As New Leaf("Leaf2")
Dim l3 As New Leaf("Leaf3")
Dim l4 As New Leaf("Leaf4")
Dim l5 As New Leaf("Leaf5")
Dim l6 As New Leaf("Leaf6")

b1.Add(l1)
b1.Add(l2)

b2.Add(l3)
b2.Add(l4)

b3.Add(l5)
b3.Add(l6)

b2.Add(b3)

Me.trunk.Add(b1)
Me.trunk.Add(b2)

End Sub


' TreeNode を生成し、返します。
Public Function CreateTreeNode() As TreeNode

Dim trunkNode As New TreeNode(Me.trunk.Name)

For Each childEntity As IEntity In Me.trunk.EntityList

Me.SetTreeNode(childEntity, trunkNode)

Next

Return trunkNode

End Function


Private Sub SetTreeNode(ByVal entity As IEntity, ByVal parentNode As TreeNode)

Dim currentNode As New TreeNode(entity.Name)

parentNode.Nodes.Add(currentNode)

If entity.HasEntity Then

For Each childEntity As IEntity In entity.EntityList

If Not childEntity.HasEntity Then

currentNode.Nodes.Add(New TreeNode(childEntity.Name))

Else

Me.SetTreeNode(childEntity, currentNode)

End If

Next

End If

End Sub


End Class

ちょっと気になるのが葉っぱクラスの Add メソッドが例外を投げること。まぁ仕方ないといえば仕方ないんですが、うっかり使っててもコンパイルエラーにならないですよね・・・。