【WPF】リファクタリングで学ぶMVVM、Prism。その① ～ ＭＶＶＭ観点で処理を切り分ける ～ 

# はじめに
下記の記事の続きとなります。
[【WPF】リファクタリングで学ぶMVVM、Prism　ー　はじめに](https://qiita.com/furugen/items/3fe94579c97797bc20c5)

この記事では、MainWindow.xaml.csを対象にＭＶＶＭ観点でどの層に処理を任せるか？を学んでいきます。

# この章で達成すること
 - コードビハインド(MainWindow.xaml.cs)に記載されたロジックをＭＶＶＭ観点で処理の責務を分ける。

# この章で得られるもの
 - MVVMの観点で、処理の責務を決定できる。


# 責務分割の基準
MainWindow.xaml.csを分割するまえに、MVVMの各層の役割を簡単にご紹介します。

## Viewの責任
- 画面に表示する構造と外見を定義 

## ViewModelの責任
- プレゼンテーションレイヤで扱うデータのカプセル化
- プレゼンテーションロジック(イベントのハンドルなど)
- Viewに表示するためのデータストアを定義

## Modelの責任
- ビジネスロジック
- ビジネスロジックで扱うデータのカプセル化
- ViewおよびViewが行う役割以外の全て

詳細については、こちらに非常に綺麗にまとめられているのでご参照ください。
https://docs.microsoft.com/en-us/previous-versions/msp-n-p/gg405484(v=pandp.40)#sec1


# MainWindow.xaml.csの処理を列挙
MainWindow.xaml.csコードがこちらです。

```csharp:MainWindow.xaml.cs
namespace TryRefactoring
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        private string JSON_FILE_PATH = "./Assets/sampledata.json";

        public MainWindow()
        {
            InitializeComponent();

            // Jsonをシリアライズ化してサンプルデータを設定
            this.xamDataGrid.DataSource = LoadJsonFile();
        }

        private List<SampleData> LoadJsonFile()
        {
            // Jsonファイルを読み込み、デシリアライズ化し、SampleDataに設定します。
            string fileContent = System.IO.File.ReadAllText(JSON_FILE_PATH);
            return JsonConvert.DeserializeObject<List<SampleData>>(fileContent);
        }

        private void addBtnClick(object sender, RoutedEventArgs e)
        {
            // 行を追加する
            List<SampleData> records = this.xamDataGrid.DataSource as List<SampleData>;
            records.Add(new SampleData());
            this.xamDataGrid.DataSource = null;
            this.xamDataGrid.DataSource = records;
        }

        private void deleteBtnClick(object sender, RoutedEventArgs e)
        {
            // 選択行を削除する。
            List<SampleData> records = this.xamDataGrid.DataSource as List<SampleData>;
            records.Remove((SampleData)this.xamDataGrid.ActiveDataItem);
            this.xamDataGrid.DataSource = null;
            this.xamDataGrid.DataSource = records;
        }


        private void fixBtnClick(object sender, RoutedEventArgs e)
        {
            SampleData editData = this.xamPropGrid.SelectedObject as SampleData;
            List<SampleData> records = this.xamDataGrid.DataSource as List<SampleData>;
            SampleData targetData = records.First(data => data.Id == editData.Id);

            // 編集内容を反映
            targetData.Age = editData.Age;
            targetData.Name = editData.Name;

            // XamDataGridに反映
            this.xamDataGrid.DataSource = null;
            this.xamDataGrid.DataSource = records;

            // データソース反映時に選択行が解除されるため、再設定
            this.xamDataGrid.SelectedDataItem = targetData;

        }

        private void XamDataGrid_RecordActivated(object sender, Infragistics.Windows.DataPresenter.Events.RecordActivatedEventArgs e)
        {
            // 選択行のオブジェクトをXamPropertyGridに表示
            xamPropGrid.SelectedObject = this.xamDataGrid.ActiveDataItem;
        }

    }
}
```

ソースコードをもとに、MainWindow.xaml.csが行っている処理を下記のように列挙しました。

- コントロールへ、データの反映
    - グリッド(XamDataGrid)への社員情報データを反映
    - グリッド(XamDataGrid)の選択行の内容を編集エリアに反映
- イベント処理
    - 行追加ボタンクリック時のイベントのハンドリング
    - 行削除ボタンクリック時のイベントのハンドリング 
    - 編集内容を確定ボタンクリック時のイベントのハンドリング
- データの削除、追加、更新
    - 社員情報データをストア
    - 社員情報データにレコードを追加
    - 社員情報データからレコードを削除
    - 編集内容(XamPropetyGrid)を元に、社員情報データを更新
- 外部からのデータ読込
    - JSONファイル(社員情報)の読込
    - JSONファイル(社員情報)の読み込んだ内容をクラス化

### MainWindow.xaml.csの債務分割
それでは、**責務分割の基準**を参考に、それぞれの処理を各層に分類してみましょう。

- コントロールへのデータを表示
    - グリッド(XamDataGrid.)への社員情報データを反映
    - グリッド(XamDataGrid)の選択行の内容を編集エリアに反映

　**［振り分け］**
　　プレゼンテーションレイヤで扱うデータを定義するため、 **ViewModel** で対応します。

- イベント処理
    - 行追加ボタンクリック時のイベントのハンドリング
    - 行削除ボタンクリック時のイベントのハンドリング 
    - 編集内容を確定ボタンクリック時のイベントのハンドリング

　**［振り分け］**
　　ユーザインタラクションの処理のため、 **ViewModel** で対応します。



- データの削除、追加、更新
    - 社員情報データをストア
    - 社員情報データにレコードを追加
    - 社員情報データからレコードを削除
    - 編集内容(XamPropetyGrid)を元に、社員情報データを更新

　**［振り分け］**
　　ビジネスロジックおよびビジネスロジックで扱うデータ管理のため、 **Model** で対応します。



- 外部からのデータ読込
    - JSONファイル(社員情報)の読込
    - JSONファイル(社員情報)の読み込んだ内容をクラス化

　**［振り分け］**
　　ビジネスロジックおよびビジネスロジックで扱うデータ管理のため、 **Model** で対応します。



# まとめ
MainWindow.xaml.csの処理を列挙し、ＭＶＶＭの各層への振り分けを決めました。
次の章から、ViewModelおよびModelの外枠を作り、各処理を分割していきましょー。

#次の記事

[【WPF】リファクタリングで学ぶMVVM、Prism。その② ～ Model,ViewModelを作成 ～](https://qiita.com/furugen/items/da62d3364a2bdb59e04e)