🙆

MVVMとは?WPFで学ぶモダンなUI設計パターン」

に公開

MVVMパターンについて学んだことを記事にしてみます!

MVVMとは??

Model-View-ViewModelの頭文字をとったものです
UIを持つソフトウェアに適用されるアーキテクチャの一つになります。

簡単なサンプル構成(

c#
MyApp/
├── Models/
│   └── Person.cs
├── ViewModels/
│   └── MainViewModel.cs
├── Views/
│   └── MainWindow.xaml
└── App.xaml

MVVMはソフトウェアをModel,View,ViewModelの3要素に分割して考える設計手法になります。

Model

「Model」はアプリケーションのデータとビジネスロジックを担当する層です。
データベースやAPIから取得した情報を保持・加工する
UIのことは一切考えない(言い過ぎかもだけど)と思っていただければ大丈夫です

View

「View」はUIの見た目(レイアウトやコントロール)を定義する層です。

ViewModel

ViewとModelの橋渡しをする層です。
ViewModelは、ユーザーインターフェース(View)がModelのデータにアクセスできるようにし、バインディングを通してUIの更新を行う役割を担います。
. 機能
データの仲介 ModelのデータをViewにバインド可能な形で提供
.プロパティ変更通知 INotifyPropertyChanged インターフェースでUIに変更を通知
.Modelとのやり取り 必要なときにModelのデータを取得・加工する

MVVMを使う理由

テストがしやすくなる(Viewを抜きにしてテスト可能)

保守性が高くなる(役割が分かれていて見通しがよい)

チーム開発に強い(デザイナーとエンジニアの作業分離が可能)

実際に仕事でMVVMを使ってみて感じたのは、役割分担がめっちゃしやすいし、オブジェクト指向コードを組みやすいと思いました。

データバインディングの例(TextBoxとTextBlockでリアルタイムに表示)

// C# 
// MainViewModel.cs
pubilic class MainViewModel : INotifyPropertyChanged
{
    private string _name;
    private string name
    {
        get { retrun _name}
    }
    set
    {
        _name = value;
        OnPropertyChanged("name");
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName) =>
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

C#
<!-- MainWindow.xaml -->
<Window ...>
    <Grid>
        <TextBox Text="{Binding name, UpdateSourceTrigger=PropertyChanged}" />
        <TextBlock Text="{Binding name}" />
    </Grid>
</Window>

実際にどうなる?

このバインディングを使うと、TextBoxに入力した文字がViewModelのNameプロパティに即座に反映され、同時にTextBlockにもその値がリアルタイムで表示されるようになります!
たとえば、TextBoxに「山田太郎」って打つと、そのまま下のTextBlockにも「山田太郎」って出る。
データとUIがしっかりつながってるのが実感できる仕組みですね

よくある落とし穴とその対処法

INotifyPropertyChanged を忘れる
UpdateSourceTrigger を指定しないため、バインディングが反映されない
DataContext をうまく渡せていない

まとめ

MVVMは慣れると非常に強力
規模が大きくなるほど恩恵が大きい
小さなアプリでも、MVVMで書いておくと将来の拡張が楽
MVVMはC#だけじゃなくて、PythonのDjangoやKotlinなど様々な言語で使われてる設計パターンなのでぜひ使ってみてください!!

Discussion