2006 年 5 月 16 日 18 時 56 分

PuzzleHintCollection: ヒント格納不変クラス


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


さて、昨日の考察ででてきた、
ヒント値の配列のラッパを作成しよう。
列挙はできないが PuzzleHintCollection という名前にする。

不変クラスということで、値の設定はコンストラクタのみ。
コンストラクタで受け取るのは、ヒント値の配列だ。
IPuzzleLoader との親和性を考えて、
ArrayList で受け取る形にしよう。

後は参照系のプロパティが殆どという形となる。
例によって必要なプロパティを洗い出す。

・ヒントの値:(インデクサ・読み取り専用)
・ヒント数:Count

実はこれだけだ。あとは、内部で後々使えそうなものを、
Friend プロパティとして追加しとこう。

・ヒントの数値合計: Total
・ヒント全体が占有する最小の長さ: MinimumLength

不変オブジェクトは値が変更されないため、
プロパティ値のキャッシュを効かせやすい。
Total や MinimumLength などは、
ヒント値の配列から計算できるが、
最初に一度だけ計算して記憶しておくと速くなる。

Friend は、内部(internal)アクセスを意味し、
同じプロジェクト内でしか参照できない。
Excel VBA では、外から参照とかは考えにくいが、
今後ソースを移植する時のことを考えておく。

では、実装してみよう。

========== クラスモジュール: PuzzleHintCollection ==========

Option Explicit

'##################################################
'# 行または列のヒントを格納した不変クラス
'##################################################

' ヒント値
Private m_oHints() As Long

' 統計情報(キャッシュ)
Private m_lTotal            As Long
Private m_lMinimumLength    As Long

' コンストラクタ代わり
Friend Sub Construct(ByVal HintValues As ArrayList)
    Dim i  As Long

    ReDim m_oHints(0 To HintValues.Count - 1)

    ' ヒント値をコピーすると共に、
    ' 統計情報を先に計算しておく
   
    m_lTotal = 0
    For i = 0 To HintValues.Count - 1
        m_oHints(i) = CLng(HintValues(i))
        m_lTotal = m_lTotal + m_oHints(i)
    Next
    m_lMinimumLength = m_lTotal + HintValues.Count - 1

End Sub

' ヒントの数値を取得する(既定のプロパティ)
Public Property Get Item(ByVal Index As Long) As Long
    Item = m_oHints(Index)
End Property

' ヒント数を取得する
Public Property Get Count() As Long
    Count = UBound(m_oHints) + 1
End Property

' ヒントの数の合計を取得する
Friend Property Get Total() As Long
    Total = m_lTotal
End Property

' ヒント全体が占有する最小の長さを返す
Friend Property Get MinimumLength() As Long
    MinimumLength = m_lMinimumLength
End Property

========== end of PuzzleHintCollection ==========

コンストラクタでの引数チェックはしていない。
Nothing が渡されたり ArrayList が 0 要素だと問題がある。
また、ヒント値が負の値とか、数値でないとか、
調べなければならないことは沢山ある。
(Long の配列を ByRef で受けるって手もあったが)

後は、ArrayList の時のようにトリックを使って、
Item プロパティに既定属性を付けるだけだ。

エクスポートし、テキストエディタで開き、
Property Get Item の下の行に以下を追加する。

Attribute Item.VB_UserMemId = 0

    ' ヒントの数値を取得する(既定のプロパティ)
    Public Property Get Item(ByVal Index As Long) As Long
    Attribute Item.VB_UserMemId = 0
        Item = m_oHints(Index)
    End Property

後は保存してインポートで OK。

プロパティを読み取り専用とし、
Public プロパティの値に関わるフィールドを
変更するメソッドを定義しなければ、
不変クラスのできあがりだ。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.