VBScriptを再定義する:Class構文で構築する堅牢なレガシーアーキテクチャ
VBScriptは「古い」のではない。「極限まで洗練された、OS直結のミニマリスト言語」である。
多くのエンジニアが、VBScriptを「使い捨てのスパゲッティコード」の溜まり場にしている。だが、それは言語のせいではない。カプセル化という設計思想を放棄し、手続き型の海に溺れている設計側の怠慢だ。
今日は、VBScriptの `Class` 構文を極限まで使い倒し、レガシー環境における保守性の境界線を書き換えるテクニックを伝授する。
—
1. なぜ今、VBScriptでオブジェクト指向なのか
大規模なシステム管理スクリプトにおいて、グローバル変数の乱立は「死」を意味する。`Class` を用いる理由はただ一つ。「状態を隠蔽し、責任を局所化する」ためだ。
WSH(Windows Script Host)環境は、メモリ管理が極めてシビアだ。オブジェクトのライフサイクルを制御できないコードは、数万行のログ処理を行うだけでリソースリークを引き起こす。クラスを活用することで、`Class_Terminate` イベントによる確実な後始末(COMオブジェクトの解放など)を実現できる。
—
2. 実践:疎結合を実現するクラス実装モデル
単なるデータの保持ではない。外部API連携やファイルシステム操作をカプセル化した、プロフェッショナルなクラス実装例を示す。
‘ クラス名: FileLogger
‘ 用途: 排他的ファイル書き込みとリソース管理の自動化
Class FileLogger
Private m_fso, m_ts, m_filePath
‘ インスタンス生成時の初期化
Private Sub Class_Initialize()
Set m_fso = CreateObject(“Scripting.FileSystemObject”)
End Sub
‘ インスタンス破棄時のクリーンアップ(メモリリーク防止の要)
Private Sub Class_Terminate()
If Not m_ts Is Nothing Then m_ts.Close
Set m_ts = Nothing
Set m_fso = Nothing
End Sub
‘ Property Let: 書き込み先の動的変更を安全に制御
Public Property Let FilePath(value)
m_filePath = value
End Property
‘ 公開メソッド: 責務を内部に隠蔽
Public Sub WriteLog(message)
If m_filePath = “” Then Err.Raise 9, , “FilePathが未設定です。”
Set m_ts = m_fso.OpenTextFile(m_filePath, 8, True)
m_ts.WriteLine “[” & Now & “] ” & message
m_ts.Close
Set m_ts = Nothing
End Sub
End Class
‘ 利用側のコード
Dim logger: Set logger = New FileLogger
logger.FilePath = “C:\logs\system.log”
logger.WriteLog “Critical Process Started.”
‘ 明示的な解放(VBScriptの必須作法)
Set logger = Nothing
—
3. シニアエンジニアが知るべき「見えない設計」
メモリ最適化とオブジェクト解放の鉄則
VBScriptのガベージコレクションを信用してはならない。特に `ADODB.Connection` や `WScript.Shell` などのCOMオブジェクトを使用する場合、`Set obj = Nothing` を怠れば、そのプロセスが終了するまでメモリは解放されない。特にループ内でオブジェクトを生成する場合、`Class_Terminate` への信頼は命綱となる。
Windows API呼び出しの真髄
VBScript単体ではWindows APIを直接叩けないが、`ScriptControl` や、COMサーバーを経由したラッパークラスを設計することで、擬似的にAPIの恩恵を受けられる。クラス内にDLL呼び出しのためのラッパーを実装することで、上位ロジックは「APIの複雑さ」から解放されるのだ。
メンテナンス性を高める「Property」の活用
`Public` 変数をそのまま晒すのは、プログラミングとして二流だ。必ず `Property Let/Set/Get` を使用せよ。これにより、値の代入時に「バリデーション(入力値検証)」を挟むことが可能になる。
‘ 悪手: 外部から自由に変更される
‘ Public Timeout
‘ 善手: 範囲外の値を拒絶するカプセル化
Private m_timeout
Public Property Let Timeout(value)
If value < 0 Or value > 3600 Then
Err.Raise 5, , “Timeout値は0から3600の間である必要があります。”
End If
m_timeout = value
End Property
—
4. 結び:レガシーを「レガシー」で終わらせないために
VBScriptは、現代的なモダン言語に比べれば機能は制限されている。しかし、その制限こそが設計者の腕を試すキャンバスだ。
クラスを定義し、責務を分離し、ライフサイクルを制御する。この当たり前のことを、VBScriptという制約の多い環境で完璧にやり遂げること。それが、真の業務自動化エンジニアの矜持だ。
コードは、書いた本人だけのものではない。半年後の君が、あるいは次の担当者が、呪文のようなコードに絶望しないために。今すぐグローバル変数を排し、クラスによる構築へと舵を切るべきだ。
技術は常に進化するが、アーキテクチャの真理は不変である。VBScriptの深淵を掌握し、誰にも侵食されない堅牢な自動化基盤を築き上げよ。
