グローバル変数の倒し方3
前回は
グローバル変数への書き込みがあるメソッドについて、グローバル変数との依存を切る方法を紹介した。
今回は
下からグローバル変数への書き込みを無くす戦略について説明する。
前回の作業で一番下の書き込みと思われる UpdateApplePrice をリファクタリングしたが、その代わり Main でグローバル変数への書き込みが増えてしまっている。実はグローバル変数への書き込みの数は減っていなかったのだ。
グローバル変数への書き込みを無くすために、グローバル変数の読み取り(コピー)を先に減らす。
今回注目するのはこの部分
UpdateApplePrice(price)
ApplePrice = price
PrintApplePrice(ApplePrice)
PrintApplePrice に注目してみる。PrintApplePrice メソッド自体は ApplePrice との依存は無くなっているが、呼び出し側の Main メソッドでは ApplePrice の読み取りという形でこのグローバル変数と依存している。この読み取り依存も消せる。
最終行において、ローカル変数 price と グローバル変数 ApplePrice は同じ値なので
PrintApplePrice(ApplePrice)
は
PrintApplePrice(price)
に置き換えることができる。その結果こうなった
Sub Main()
ApplePrice = 100
PrintApplePrice(ApplePrice)
Dim price = ApplePrice
UpdateApplePrice(price)
ApplePrice = price
PrintApplePrice(price)
End Sub
ApplePrice への書き込みの後ろの参照が完全に消えた。
この時点で、ApplePrice にどのような書き込みをしようが、逆に書き込みをしなかろうが、影響するものは何もない。
グローバル変数への書き込みが不要になった。
Sub Main()
ApplePrice = 100
PrintApplePrice(ApplePrice)
Dim price = ApplePrice
UpdateApplePrice(price)
PrintApplePrice(price)
End Sub
一番下のグローバル変数への書き込みが消えた。
現在のコードは以下。ApplePrice が使われる範囲が上の方に集まって小さくなってることが分かると思う。
Option Explicit On
Option Strict On
Option Infer On
Module Program
Dim ApplePrice As Integer = 0
Sub PrintApplePrice(applePrice As Integer)
Console.WriteLine("{0}円", applePrice)
End Sub
Sub UpdateApplePrice(ByRef price As Integer)
Console.Write("{0}円から、", price)
price = 80
Console.WriteLine("{0}円に更新", price)
End Sub
Sub Main()
ApplePrice = 100
PrintApplePrice(ApplePrice)
Dim price = ApplePrice
UpdateApplePrice(price)
PrintApplePrice(price)
End Sub
End Module
次回は
作業を繰り返すことによってグローバル変数を消せることを示したいと思う。