Rahmenクラスの修正

Rahmenクラスの修正

前回

akashi-keirin.hatenablog.com

Rahmenクラスを修正した。

生まれ変わったRahmenクラス

クラスモジュール Rahmen
Option Explicit

'///Attribute VB_PredeclaredId = True///'

Public Enum NoodleSolidity
  nsYugeTooshi
  nsKonaOtoshi
  nsHarigane
  nsBariKata
  nsKata
  nsFutsuu
  nsYawa
  nsZundare
End Enum

Private count_ As Long

Private solidity_ As String
Private isInstantiating_ As Boolean

Public Property Get Solidity() As String
  Solidity = solidity_
End Property

Public Property Let Count(ByVal value_ As Long)'……(1)'
  count_ = value_
End Property
Public Property Get Count() As Long
  Count = count_
End Property

Public Property Get Kaedama() As String
  Kaedama = CStr(count_) & "玉目"
End Property

Public Property Let IsInstantiating( _
                      ByVal value_ As Boolean)'……(2)'
  isInstantiating_ = value_
End Property

Private Sub Class_Initialize()
  solidity_ = "ふつう"
End Sub

Public Sub setSolidity(ByVal solidityArg As NoodleSolidity)
  solidity_ = getSolidityString(solidityArg)
End Sub

Private Function getSolidityString( _
             ByVal arg As NoodleSolidity) As String
  Dim ret As String
  Select Case arg
    Case nsYugeTooshi: ret = "湯気とおし"
    Case nsKonaOtoshi: ret = "粉落とし"
    Case nsHarigane: ret = "ハリガネ"
    Case nsBariKata: ret = "バリカタ"
    Case nsKata: ret = "カタ"
    Case nsFutsuu: ret = "ふつう"
    Case nsYawa: ret = "やわ"
    Case nsZundare: ret = "ずんだれ"
    Case Else: ret = "ち~んw"
  End Select
  getSolidityString = ret
  If Not isInstantiating_ Then _
    count_ = Rahmen.Count + 1: Rahmen.Count = count__'……(3)'
End Function

Public Function getInstance( _
            ByVal solidity__ As NoodleSolidity) As Rahmen
  Dim ret As New Rahmen
  ret.IsInstantiating = True'……(4)'
  Call ret.setSolidity(solidity__)
  count_ = Rahmen.Count + 1
  ret.Count = count_
  Set getInstance = ret
  ret.IsInstantiating = False
End Function

変更点が結構ある。

Countプロパティ

まずは、(1)の

Public Property Let Count(ByVal value_ As Long)
  count_ = value_
End Property
Public Property Get Count() As Long
  Count = count_
End Property

CountプロパティがRead/Writeになってしまった。もはやPublicにしようぜ、と言いたくなるレベル。

結局、Rahmenはあくまでインスタンスであり、インスタンス間で値をやりとりするにはこうするほかないのだ。「クラス変数」といっても、所詮「クラス変数っぽい」ものに過ぎない、ということ。

IsInstantiatingプロパティ

次に、IsInstantiatingプロパティ。

これは、getInstance実行中かどうかを判定するためのもの。

〈麺のかたさ〉を設定するgetSolidityStringメソッドが呼ばれる状況は、二通りある。getInstanceメソッドを実行したときと、直接setSolidityメソッドが呼ばれた場合の二通り。

Rahmen.getInstanceメソッドのときは、既定のインスタンスRahmenが持っているcount_の値を、メソッド内で直接インスタンスret)のCountプロパティを通じてインスタンスret)内部の変数Countcount_にセットすることができる。(あー、ややこしい!)

しかし、Rahmen.getInstanceによって生み出されたインスタンスsetSolidityを実行した場合、既定のインスタンスRahmenとは縁が切れてしまっているので、既定のインスタンスRahmenが持っているcount_の値をインスタンスに渡す処理が要る。(ホンマにややこしい! 書いていてわけわかんなくなる!)

そこで、Rahmen.getInstance実行中は、新たに生み出されたインスタンスIsInstantiatingプロパティをTrueにしておいて、getSolidityStringメソッド内の(3)

count_ = Rahmen.Count + 1: Rahmen.Count = count_

が実行されないようにしておく。

逆に、新たに生み出されたインスタンスsetSolidityメソッド実行時には、インスタンスIsInstantiatingプロパティはFalseなので、

count_ = Rahmen.Count + 1: Rahmen.Count = count_

が実行され、新たに生み出されたインスタンス側のcount_の値をインクリメントするとともに、既定のインスタンスRahmenCountプロパティもインクリメントされることになる。

使ってみる

次のコードで実験。

リスト1 標準モジュール
Public Sub disposable01()
  Dim rahmen1 As Rahmen
  Set rahmen1 = Rahmen.getInstance(nsKonaOtoshi)
  Dim rahmen2 As Rahmen
  Set rahmen2 = Rahmen.getInstance(nsBariKata)
  Dim rahmen3 As Rahmen
  Set rahmen3 = Rahmen.getInstance(nsZundare)
  Call printData(rahmen1)
  Call printData(rahmen2)
  Call printData(rahmen3)
  Debug.Print Rahmen.Kaedama
  Call rahmen3.setSolidity(nsHarigane)  '……(4)'
  Call printData(rahmen3)
  Call rahmen2.setSolidity(nsYawa)  '……(5)'
  Call printData(rahmen2)
  Debug.Print String(40, "=")
End Sub

Private Sub printData(ByVal targetRahmen As Rahmen)
  With targetRahmen
    Debug.Print "替え玉:" & .Kaedama; _
                "/麺のかたさ:" & .Solidity
  End With
End Sub

前回のリスト1に加え、(4)の

Call rahmen3.setSolidity(nsHarigane)
Call printData(rahmen3)

で、インスタンスrahmen3で、新たに「ハリガネ」で替え玉を注文し、さらに(5)の

Call rahmen2.setSolidity(nsYawa)
Call printData(rahmen2)

で、インスタンスrahmen2で、新たに「やわ」で替え玉を注文した。

実行結果

一回目。

f:id:akashi_keirin:20190503001253j:plain

二回目。

f:id:akashi_keirin:20190503001255j:plain

ちゃんと通しの替え玉数が表示された。

おわりに

しかしながら、Countプロパティに加え、IsInstantiatingプロパティまで外部から変更可能になってしまった。

所詮は擬似、このあたりが限界なのだろうか……。

追記

このシリーズは続きません。もうやめます。