こんにちは。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は古い言語だと言われることもありますが、正しい設計で書かれたコードは、どんな言語にも負けないほど堅牢で美しいものです。
「動けばいい」コードから「テスト可能な」コードへ。
その一歩を踏み出したあなたなら、必ず素晴らしいエンジニアになれます。応援していますよ!
