【入門編】レガシーVB.NETコードのリファクタリング手法:巨大なコードビハインド(God Class)をMVPパターンで分離しテスト容易性を高める – Visual Basic (VB / VB.NET)解析バイブル

スポンサーリンク

こんにちは。VB.NETの世界へようこそ。
数千行に及ぶ「フォームのコードビハインド」……いわゆる「God Class(神クラス)」に頭を抱える毎日を送っていませんか?

「ボタンを押したら計算して、DBに保存して、画面のラベルを書き換えて……」と、一つの場所に全てを詰め込むのは、一見楽に見えます。しかし、それは「修正するたびに別の場所が壊れる」という、メンテナンス地獄への入り口です。

今日は、伝説のアーキテクトである私が、その巨大な悪夢をMVP(Model-View-Presenter)パターンで解体し、テスト可能な「美しいコード」へと昇華させる極意を伝授します。

1. なぜ「God Class」は悪なのか?

VB.NETのフォーム(`Form1.vb`など)は、本来「UIの表示」を担当する場所です。ここにビジネスロジック(計算やDB操作)が混ざると、以下のような致命的な問題が発生します。

  • テストが不可能: 画面を表示させないとロジックが動かせない。
  • 変更に弱い: UIを少し変えただけで、裏側の計算ロジックまでバグる。
  • 再利用性がゼロ: 別の画面で同じ計算をしたいとき、コードをコピペするしかない。

これらを解消するのが「責務の分離」です。

2. MVPパターン:UIとロジックの「離婚」

MVPパターンでは、役割を3つに切り分けます。

1. View(フォーム): 画面表示のみ。「ボタンが押された」という事実だけをPresenterに伝える。
2. Presenter(司令塔): Viewからの入力を受け取り、Modelに指示を出し、結果をViewに反映させる。
3. Model(ビジネスロジック): DB操作や計算のみを行う。UIのことは一切知らない。

3. 実践:巨大フォームを解体する

例として、「ユーザー名を入力して保存ボタンを押す」だけの単純な機能をリファクタリングしてみましょう。

Step 1: 契約書(Interface)を作る

まず、ViewとPresenterが会話するための「ルール(インターフェース)」を定義します。

‘ ViewがPresenterに何をしてほしいか、何を見せるべきかを定義
Public Interface IUserView
Property UserName As String
Sub ShowMessage(message As String)
End Interface

Step 2: Presenter(ロジックの受け皿)の実装

フォームからロジックをここに追い出します。

Public Class UserPresenter
Private ReadOnly _view As IUserView

‘ コンストラクタでViewを受け取る(依存性の注入)
Public Sub New(view As IUserView)
_view = view
End Sub

‘ フォームのボタンから呼ばれるメソッド
Public Sub SaveUser()
If String.IsNullOrEmpty(_view.UserName) Then
_view.ShowMessage(“名前を入力してください!”)
Return
End If

‘ ここでModelを呼び出す(今回は簡易的に処理)
‘ SaveToDatabase(_view.UserName)
_view.ShowMessage(“保存しました!”)
End Sub
End Class

Step 3: Form(View)を薄くする

フォームは「ただの器」になります。

Public Class Form1
Implements IUserView

Private _presenter As UserPresenter

Public Sub New()
InitializeComponent()
_presenter = New UserPresenter(Me)
End Sub

‘ インターフェースの実装
Public Property UserName As String Implements IUserView.UserName
Get Return txtUserName.Text End Get
Set(value As String) txtUserName.Text = value End Set
End Property

Public Sub ShowMessage(message As String) Implements IUserView.ShowMessage
MessageBox.Show(message)
End Sub

‘ UIイベントだけを処理し、Presenterに丸投げする
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
_presenter.SaveUser()
End Sub
End Class

4. なぜこれが「最強」なのか?

この構成の凄みは「テスト容易性」にあります。

Presenterは「`IUserView`というインターフェース」しか知りません。つまり、テストをする際に本物のフォームを用意する必要がないのです。ダミーのViewクラスを作ってPresenterに渡せば、ボタン一つ押さずにビジネスロジックを自動テストできます。

初学者が陥りやすい罠

  • 「難しく考えすぎる」: 最初から完璧を目指さず、まずは「ロジックを別のクラスに切り出す」ことだけ意識してください。
  • 「Viewを直接操作しようとする」: Presenterの中から直接 `Form1.Label1.Text = …` と書くのはNGです。必ずインターフェースを経由しましょう。

最後に:コードは「育てる」もの

数千行のコードを一度に書き換える必要はありません。まずは一番汚い「ボタンクリックイベント」の中身を、Presenterへ一行ずつ追い出してみてください。

VB.NETは古い言語だと言われることもありますが、正しい設計で書かれたコードは、どんな言語にも負けないほど堅牢で美しいものです。

「動けばいい」コードから「テスト可能な」コードへ。
その一歩を踏み出したあなたなら、必ず素晴らしいエンジニアになれます。応援していますよ!