WinFormsで学ぶ MVP パターン入門


1. MVPパターンとは?

MVP(Model-View-Presenter)は、GUIアプリケーションの設計パターンの一つです。「UIとロジックを分離」 し、コードの可読性と保守性を向上させることが目的です。

1.1 MVPの構成

MVPは以下の3つの要素で構成されます。

  • Model(M)
    • アプリケーションのデータやビジネスロジックを担当
    • 例:データベースとのやり取りやデータの計算処理
  • View(V)
    • ユーザーに表示するUI
    • 例:WinFormsのFormUserControl
    • ロジックを持たず、表示のみに徹することが重要
  • Presenter(P)
    • ModelとViewの橋渡しを担当
    • ユーザーの操作を受け取り、適切な処理をModelに指示し、結果をViewに反映

1.2 MVPと他のパターンとの違い

パターン目的特徴
MVC(Model-View-Controller)UIとロジックの分離Web開発に適している。WinFormsには不向き
MVVM(Model-View-ViewModel)データバインディングを活用WPF向き。WinFormsではデータバインディングが弱い
MVP(Model-View-Presenter)WinForms向けの分離イベント駆動型のUIに適している

2. WinFormsでMVPを学ぶチュートリアル

2.1 チュートリアルの概要

このチュートリアルでは、「名前」と「年齢」を入力し、ボタンを押すとラベルに表示されるアプリ を作成します。
このアプリをMVPパターンで設計し、ロジックとUIを分離 します。


ステップ1:プロジェクトを作成

  1. Visual Studioを開く
  2. 「Windowsフォームアプリ(.NET)」 を選択し、新規プロジェクトを作成
  3. プロジェクト名を「MvpExample」にする

ステップ2:Model(データ)を作成

データを保持するUserModelクラスを作成します。

ファイル名: UserModel.cs

public class UserModel
{
    public string Name { get; set; }
    public int Age { get; set; }
}

ポイント:

  • UserModel はデータを管理するため、UIの影響を受けません。
  • ビジネスロジック(計算やデータベース操作など)をこのクラスに追加できます。

ステップ3:View(画面)を作成

  1. UserForm.cs(フォームデザイン)を開く
  2. 以下のUIを追加
    • TextBox(名前入力用)NameTextBox
    • TextBox(年齢入力用)AgeTextBox
    • Button(表示ボタン)ShowButton
    • Label(出力用)OutputLabel

次に、Viewのインターフェースを定義します。

ファイル名: IUserView.cs

public interface IUserView
{
    string UserName { get; set; }
    int UserAge { get; set; }
    void ShowMessage(string message);
    event EventHandler ShowUserInfo;
}

ポイント:

  • View(UserForm)が実装すべきインターフェースを定義
  • event EventHandler ShowUserInfo; でボタンが押されたときのイベントを通知する

ステップ4:View(UserForm)を実装

ファイル名: UserForm.cs

public partial class UserForm : Form, IUserView
{
    public event EventHandler ShowUserInfo;

    public string UserName
    {
        get => NameTextBox.Text;
        set => NameTextBox.Text = value;
    }

    public int UserAge
    {
        get => int.TryParse(AgeTextBox.Text, out int age) ? age : 0;
        set => AgeTextBox.Text = value.ToString();
    }

    public UserForm()
    {
        InitializeComponent();
        ShowButton.Click += (s, e) => ShowUserInfo?.Invoke(this, EventArgs.Empty);
    }

    public void ShowMessage(string message)
    {
        OutputLabel.Text = message;
    }
}

ポイント:

  • UIのイベント処理をPresenterに委譲
  • ShowUserInfo イベントを発生させ、Presenterに通知
  • UIの更新は ShowMessage() のみが担当し、ロジックは書かない

ステップ5:Presenter(ロジック)を作成

ファイル名: UserPresenter.cs

public class UserPresenter
{
    private readonly IUserView view;
    private readonly UserModel model;

    public UserPresenter(IUserView view)
    {
        this.view = view;
        this.model = new UserModel();

        this.view.ShowUserInfo += OnShowUserInfo;
    }

    private void OnShowUserInfo(object sender, EventArgs e)
    {
        // Modelにデータを設定
        model.Name = view.UserName;
        model.Age = view.UserAge;

        // Viewに結果を表示
        string message = $"名前: {model.Name}, 年齢: {model.Age}";
        view.ShowMessage(message);
    }
}

ポイント:

  • Viewからのイベント (ShowUserInfo) を受け取る
  • Modelにデータをセットし、Viewに結果を渡す
  • Presenterは直接UIを操作せず、Viewのインターフェースを通じて更新を指示する

ステップ6:アプリを起動

Program.cs でPresenterを初期化します。

ファイル名: Program.cs

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    UserForm form = new UserForm();
    UserPresenter presenter = new UserPresenter(form);

    Application.Run(form);
}

ポイント:

  • UserForm のインスタンスを作成
  • UserPresenterUserForm を渡し、MVPパターンを構築

7. まとめ

  1. Model(データ管理)UserModel にユーザー情報を保持
  2. View(画面)UserForm でUIの処理のみ担当
  3. Presenter(ロジック)UserPresenter で処理を制御

このパターンを学ぶことで、ロジックとUIの分離 ができ、WinFormsアプリをより保守しやすく、テストしやすい構造にできます。

MVPパターンを習得すれば、さらに WPFのMVVMやASP.NET MVC に進むこともスムーズになります。

クラス図

このクラス図は、MVP(Model-View-Presenter)パターンを示しています。

このクラス図の関係を説明すると:

  • IUserView は UserForm に実装される。
  • UserPresenter は IUserView を使用し、ModelとViewの橋渡しをする。
  • UserModel はユーザーのデータを保持し、UserPresenter が利用する。
  • Program は UserForm と UserPresenter をインスタンス化し、アプリを開始する。

MVPパターンのメリット

項目直接Formにロジックを書くMVPパターン
コードの分離UIとロジックが混在明確に分離される
メンテナンス性変更が大変変更が容易
テストのしやすさフォームのテストが難しいPresenter単体でテスト可能
再利用性他のプロジェクトで使いにくいロジックを他のUIに適用可能

MVPパターンを使うことで、WinFormsアプリの品質を向上できる。


まとめ

  1. Model(データ管理) を作成する
  2. View(UI) はUI表示のみ担当する
  3. Presenter(ロジック) はModelとViewの仲介役
  4. MainメソッドでPresenterをセットアップし、MVPを実装する

WinFormsアプリを作るときはMVPパターンを意識すると、コードの管理がしやすくなります。