狠狠撸

狠狠撸Share a Scribd company logo
MVPVMパターン

えムナウ (児玉宏之)
http://mnow.jp/
http://mnow.wankuma.com/
http://blogs.wankuma.com/mnow/
http://www.ailight.jp/blog/mnow/
アジェンダ

?   はじめに
?   MVPVM 設計パターン
?   ナビゲーション
?   プレゼンター
?   まとめ
はじめに

? MSDN マガジン2011年12月号で発表された
  「MVPVM 設計パターン」ですが、私もViewと
  ViewMode?lの両方を知っていて現状の画面
  状態を管理する何者かが?必要なことは感じて
  いました。
? Applicationの派生クラスやApplicat?ionが操
  作するオブジェクトとして現状の画面状態を管?
  理やナビゲーションをする機能をつくっていま
  した。今回のセッションでは私なりに研究した
  「MVPVM 設計パターン」をお届けします。
MVPVM 設計パターン

? モデル - ビュー - プレゼンター - ビューモデル
  (MVPVM: Model-View-Presenter-
  ViewModel) パターンは、 Microsoft patterns
  & practices の Prism プロジェクトで導入され
  ました。
? MVVM の能力と機能をすべて利用でき、
  MVPの拡張性からプレゼンテーションロジック
  の複雑さにも対応でき、ViewModel は本来あ
  るべきプロパティ公開とコマンドの受付になり
  ます。
MVPVM 設計パターン

? MVPVMパターン
 – それではMVPVMパターンとはなんでしょうか?
 – MVVMパターン と MVPパターンを合体させたも
   のです。
 – MVVMパターン と MVPパターンを見てみましょう。
MVPVM 設計パターン

? MVVMパターン
 – View:ユーザーインターフェースの外観や配置や
   反応(インタラクション)を定義する
 – ViewModel:Viewの必要な情報をプロパティで公
   開しユーザー入力やコマンドを処理する
 – Model:データの取得や管理を行いプログラムの
   処理の中核となる
MVPVM 設計パターン

? MVVMパターン


    View                             Model



                   コマンド
データバイ
ンド


                   ViewModel
           プロパティ               データ取得?更新
MVPVM 設計パターン

? MVPパターン
 – View:ユーザーインターフェースの外観や配置や
   反応(インタラクション)を定義する
 – Presenter:Viewのナビゲーションを管理しユー
   ザー入力をModelに伝える
 – Model:データの取得や管理を行いプログラムの
   処理の中核となる
MVPVM 設計パターン

? MVPパターン


   View                          Model



               入力




               Presenter
     ナビゲーション               データ取得?更新
MVPVM 設計パターン

? MVPVMパターン
 – View:ユーザーインターフェースの外観や配置や
   反応(インタラクション)を定義する
 – ViewModel:Viewの必要な情報をプロパティで公
   開しユーザー入力やコマンドをPresenterに渡す
 – Presenter:ViewやのViewModelのナビゲーショ
   ンを管理しユーザー入力をModelに伝える
 – Model:データの取得や管理を行いプログラムの
   処理の中核となる
MVPVM 設計パターン

? MVPVMパターン

                                 Presenter
                    ナビゲーション
    View                                 データ取得?更新


             コマンド
データバイ                           データ更新依頼
ンド


                    ViewModel
           プロパティ                             Model
ナビゲーション

? ナビゲーション
 – MVVMパターンではどこがナビゲーションを担当
   していたのでしょうか?
 – 答えの一つはメッセージ+ビヘイビアーです。
 – ビヘイビアーはViewの分類になります。
 – 「ViewModel から View を操作する」ということ葉
   を聞いたことがある人もいるでしょう。
 – 操作というのはメッセージを送ってメッセージボッ
   クスやダイアログを表示したりすることも多かった
   のです。
ナビゲーション
  ? メッセージボックス
public class DialogMessageBehavior : Behavior<DependencyObject>
  {
     protected override void OnAttached()
     {
        base.OnAttached();
        Messenger.Default.Register<DialogMessage>(AssociatedObject, p => Invoke(p));
     }
     protected override void OnDetaching()
     {
        base.OnDetaching();
        Messenger.Default.Unregister<DialogMessage>(AssociatedObject);
     }
     private void Invoke(object parameter)
     {
        DialogMessage message = parameter as DialogMessage;
         MessageBoxResult result = MessageBox.Show(message.Content, message.Caption,
message.Button, message.Icon, message.DefaultResult, message.Options);
         message.ProcessCallback(result);
      }
  }
ナビゲーション
  ? ダイアログ
public class DialogMessageBehavior : Behavior<Wndow>
  {
     protected override void OnAttached()
     {
        base.OnAttached();
        Messenger.Default.Register<DialogMessage>(AssociatedObject, p => Invoke(p));
     }
     protected override void OnDetaching()
     {
        base.OnDetaching();
        Messenger.Default.Unregister<DialogMessage>(AssociatedObject);
     }
     private void Invoke(object parameter)
     {
        DialogMessage message = parameter as DialogMessage;
         AssociatedObject.DataContext = message.ViewModel;
         bool? result = AssociatedObject.ShowDialog();
         message.ProcessCallback(result);
      }
  }
ナビゲーション

? ナビゲーション
  – MVVMパターンでは他にどこがナビゲーションを
    担当していたのでしょうか?
  – 答えの一つはViewModel+DataTemplateです。
<DataTemplate DataType="{x:Type c:GreekGodViewModel}">
   <TextBlock Text="{Binding Path=Name}" Foreground="Gold"/>
</DataTemplate>


  – さらに DataTemplate をデータによって切り替え
    る DataTemplateSelector というのもあります。
  – DataTemplate はViewの分類になります。
ナビゲーション

 ? DataTemplateSelector
public class TaskListDataTemplateSelector : DataTemplateSelector
{
  public override DataTemplate
         SelectTemplate(object item, DependencyObject container)
  {
     FrameworkElement element = container as FrameworkElement;
     if (element != null && item != null && item is TaskViewModel)
     {
         var taskitem = item as TaskViewModel;
         if (taskitem.Priority == 1)
             return element.FindResource("importantTaskTemplate") as DataTemplate;
         else
             return element.FindResource("myTaskTemplate") as DataTemplate;
     }
     return null;
  }
}
ナビゲーション

? MVVMパターンは、View と ViewModel は疎
  結合でお互いに交換可能であるということが
  利点の一つであるといわれていました。
? どうして今見てきたような密結合が生まれてし
  まったのでしょうか?
? ナビゲーションは View と ViewModel の両方
  を知らないとできません、この場合 View に仕
  込んでますので ViewModel や 本来
  ViewModel にあるべきデータが View に出
  てきてしまいます。
ナビゲーション

? ナビゲーション
 – MVVMパターンではViewだけがナビゲーションを
   担当していたのでしょうか?
 – 答えの一つはアプリケーションクラスです。
 – アプリケーションクラスはMVVMパターンの範囲
   外です。
 – 範囲外であれば別に問題ないのでしょうか?
 – ナビゲーションを担当する Presenter があればア
   プリケーションクラスはすっきりするはずです。
ナビゲーション
? アプリケーションクラス
protected override void OnStartup(StartupEventArgs e)
     {
        var win = new Views.TwitterWindow();
        this.MainWindow = win;
        var account = LoadAccount();
        if (account == null)
            account = NewAccountWithDialog();
        if (account != null)
            SaveAccount(account);
        else
        {
            MessageBox.Show("認証失敗");
            return;
        }
        var vm = new ViewModel.TwitterViewModel(
                    ConsumerKey, ConsumerSecret, account.Token);
        win.DataContext = vm;
        win.Show();
        base.OnStartup(e);
     }
プレゼンター

? プレゼンターの役割
 – View と ViewModel のインスタンス作成を行いま
   す。
 – View をパネルなどのコンテナに追加し、
   DataContext に ViewModel をセットします。
 – Model に表示すべきデータを要求し ViewModel
   にセットします。
 – 上位の Presenter や ViewModel の依頼により
   更新すべきデータを収集し Model を更新します。
 – View と ViewModel のインスタンス解放を行いま
   す。
プレゼンター

? プレゼンターの構成
 – Presenter はパネルなどのコンテナで複数の
   Presenter を管理する Presenter と、ユーザーコ
   ントロールやダイアログなどの単一ビューを管理
   するPresenter があります。
 – View や ViewModel が階層構造になっているよ
   うに Presenter も階層構造になります。
プレゼンター

? プレゼンターの利点
 – Application や ViewModel からプレゼンテーショ
   ンロジックを解放します。
 – View と ViewModel は疎結合でお互いに交換可
   能な状態に戻すことにより、再利用性を高め
   View や ViewModel をライブラリ化しやすくします。
 – View と ViewModel と Model 全てにアクセス可
   能な存在なので、アンドゥ?リドゥの実装場所に最
   適です。
 – ViewModel から View をクローズするメッセージ
   は必要なくなります。
プレゼンター

? 親が子供を管理
 – ダイアログ を表示させたいPresenterは ダイアロ
   グを管理するPresenterを生成して、ダイアログが
   閉じたら解放します。
 – パネルなどのコンテナを管理するPresenterは、
   パネルの中身を管理するPresenterをパネル内に
   表示するときに生成してパネルから削除されると
   きに解放します。
プレゼンター

? コンテナ内をスライドして入れ替わる




         A画面      B画面
プレゼンター

? WPFやSilverlightではこんな画面変化も可能
  ですが、この場合はコンテナとなるパネルにス
  トーリーボードを仕掛けて RenderTransform
  の TranslateTransform を変化させて表示を
  変えます。
? 最初にA画面とB画面の View と ViewModel
  を用意してA画面を表示範囲内にB画面を表
  示範囲外に設定してストーリーボードを起動し
  ます。
プレゼンター

? MVVMパターンでは、 A画面とB画面の View
  と ViewModel を知っている何かの存在が必
  要でコンテナの View で実行するとしたら、か
  なりの密結合になってしまったと思います。
プレゼンター

? MVPVMパターンでは、 A画面のPresenterは
  A画面の View と ViewModel を知っていて、
  B画面のPresenterはB画面の View と
  ViewModel を知っています、コンテナの
  Presenterはコンテナの View と ViewModel
  の他に、 A画面とB画面のPresenterを知って
  います。
? 役割分担でき疎結合性も保たれます。
まとめ

? MVPVMパターンはMVVM の能力と機能をす
  べて利用でき、 MVPの拡張性からプレゼン
  テーションロジックの複雑さにも対応できます。
? MVPVMパターンは View と ViewModel は疎
  結合でお互いに交換可能な状態に戻すのに
  有効な手段です。
? 皆さんも検討してみたらどうでしょうか?

More Related Content

RIAアーキテクチャー研究会 第3回 セッション4 Mvpvm pattern

  • 2. アジェンダ ? はじめに ? MVPVM 設計パターン ? ナビゲーション ? プレゼンター ? まとめ
  • 3. はじめに ? MSDN マガジン2011年12月号で発表された 「MVPVM 設計パターン」ですが、私もViewと ViewMode?lの両方を知っていて現状の画面 状態を管理する何者かが?必要なことは感じて いました。 ? Applicationの派生クラスやApplicat?ionが操 作するオブジェクトとして現状の画面状態を管? 理やナビゲーションをする機能をつくっていま した。今回のセッションでは私なりに研究した 「MVPVM 設計パターン」をお届けします。
  • 4. MVPVM 設計パターン ? モデル - ビュー - プレゼンター - ビューモデル (MVPVM: Model-View-Presenter- ViewModel) パターンは、 Microsoft patterns & practices の Prism プロジェクトで導入され ました。 ? MVVM の能力と機能をすべて利用でき、 MVPの拡張性からプレゼンテーションロジック の複雑さにも対応でき、ViewModel は本来あ るべきプロパティ公開とコマンドの受付になり ます。
  • 5. MVPVM 設計パターン ? MVPVMパターン – それではMVPVMパターンとはなんでしょうか? – MVVMパターン と MVPパターンを合体させたも のです。 – MVVMパターン と MVPパターンを見てみましょう。
  • 6. MVPVM 設計パターン ? MVVMパターン – View:ユーザーインターフェースの外観や配置や 反応(インタラクション)を定義する – ViewModel:Viewの必要な情報をプロパティで公 開しユーザー入力やコマンドを処理する – Model:データの取得や管理を行いプログラムの 処理の中核となる
  • 7. MVPVM 設計パターン ? MVVMパターン View Model コマンド データバイ ンド ViewModel プロパティ データ取得?更新
  • 8. MVPVM 設計パターン ? MVPパターン – View:ユーザーインターフェースの外観や配置や 反応(インタラクション)を定義する – Presenter:Viewのナビゲーションを管理しユー ザー入力をModelに伝える – Model:データの取得や管理を行いプログラムの 処理の中核となる
  • 9. MVPVM 設計パターン ? MVPパターン View Model 入力 Presenter ナビゲーション データ取得?更新
  • 10. MVPVM 設計パターン ? MVPVMパターン – View:ユーザーインターフェースの外観や配置や 反応(インタラクション)を定義する – ViewModel:Viewの必要な情報をプロパティで公 開しユーザー入力やコマンドをPresenterに渡す – Presenter:ViewやのViewModelのナビゲーショ ンを管理しユーザー入力をModelに伝える – Model:データの取得や管理を行いプログラムの 処理の中核となる
  • 11. MVPVM 設計パターン ? MVPVMパターン Presenter ナビゲーション View データ取得?更新 コマンド データバイ データ更新依頼 ンド ViewModel プロパティ Model
  • 12. ナビゲーション ? ナビゲーション – MVVMパターンではどこがナビゲーションを担当 していたのでしょうか? – 答えの一つはメッセージ+ビヘイビアーです。 – ビヘイビアーはViewの分類になります。 – 「ViewModel から View を操作する」ということ葉 を聞いたことがある人もいるでしょう。 – 操作というのはメッセージを送ってメッセージボッ クスやダイアログを表示したりすることも多かった のです。
  • 13. ナビゲーション ? メッセージボックス public class DialogMessageBehavior : Behavior<DependencyObject> { protected override void OnAttached() { base.OnAttached(); Messenger.Default.Register<DialogMessage>(AssociatedObject, p => Invoke(p)); } protected override void OnDetaching() { base.OnDetaching(); Messenger.Default.Unregister<DialogMessage>(AssociatedObject); } private void Invoke(object parameter) { DialogMessage message = parameter as DialogMessage; MessageBoxResult result = MessageBox.Show(message.Content, message.Caption, message.Button, message.Icon, message.DefaultResult, message.Options); message.ProcessCallback(result); } }
  • 14. ナビゲーション ? ダイアログ public class DialogMessageBehavior : Behavior<Wndow> { protected override void OnAttached() { base.OnAttached(); Messenger.Default.Register<DialogMessage>(AssociatedObject, p => Invoke(p)); } protected override void OnDetaching() { base.OnDetaching(); Messenger.Default.Unregister<DialogMessage>(AssociatedObject); } private void Invoke(object parameter) { DialogMessage message = parameter as DialogMessage; AssociatedObject.DataContext = message.ViewModel; bool? result = AssociatedObject.ShowDialog(); message.ProcessCallback(result); } }
  • 15. ナビゲーション ? ナビゲーション – MVVMパターンでは他にどこがナビゲーションを 担当していたのでしょうか? – 答えの一つはViewModel+DataTemplateです。 <DataTemplate DataType="{x:Type c:GreekGodViewModel}"> <TextBlock Text="{Binding Path=Name}" Foreground="Gold"/> </DataTemplate> – さらに DataTemplate をデータによって切り替え る DataTemplateSelector というのもあります。 – DataTemplate はViewの分類になります。
  • 16. ナビゲーション ? DataTemplateSelector public class TaskListDataTemplateSelector : DataTemplateSelector { public override DataTemplate SelectTemplate(object item, DependencyObject container) { FrameworkElement element = container as FrameworkElement; if (element != null && item != null && item is TaskViewModel) { var taskitem = item as TaskViewModel; if (taskitem.Priority == 1) return element.FindResource("importantTaskTemplate") as DataTemplate; else return element.FindResource("myTaskTemplate") as DataTemplate; } return null; } }
  • 17. ナビゲーション ? MVVMパターンは、View と ViewModel は疎 結合でお互いに交換可能であるということが 利点の一つであるといわれていました。 ? どうして今見てきたような密結合が生まれてし まったのでしょうか? ? ナビゲーションは View と ViewModel の両方 を知らないとできません、この場合 View に仕 込んでますので ViewModel や 本来 ViewModel にあるべきデータが View に出 てきてしまいます。
  • 18. ナビゲーション ? ナビゲーション – MVVMパターンではViewだけがナビゲーションを 担当していたのでしょうか? – 答えの一つはアプリケーションクラスです。 – アプリケーションクラスはMVVMパターンの範囲 外です。 – 範囲外であれば別に問題ないのでしょうか? – ナビゲーションを担当する Presenter があればア プリケーションクラスはすっきりするはずです。
  • 19. ナビゲーション ? アプリケーションクラス protected override void OnStartup(StartupEventArgs e) { var win = new Views.TwitterWindow(); this.MainWindow = win; var account = LoadAccount(); if (account == null) account = NewAccountWithDialog(); if (account != null) SaveAccount(account); else { MessageBox.Show("認証失敗"); return; } var vm = new ViewModel.TwitterViewModel( ConsumerKey, ConsumerSecret, account.Token); win.DataContext = vm; win.Show(); base.OnStartup(e); }
  • 20. プレゼンター ? プレゼンターの役割 – View と ViewModel のインスタンス作成を行いま す。 – View をパネルなどのコンテナに追加し、 DataContext に ViewModel をセットします。 – Model に表示すべきデータを要求し ViewModel にセットします。 – 上位の Presenter や ViewModel の依頼により 更新すべきデータを収集し Model を更新します。 – View と ViewModel のインスタンス解放を行いま す。
  • 21. プレゼンター ? プレゼンターの構成 – Presenter はパネルなどのコンテナで複数の Presenter を管理する Presenter と、ユーザーコ ントロールやダイアログなどの単一ビューを管理 するPresenter があります。 – View や ViewModel が階層構造になっているよ うに Presenter も階層構造になります。
  • 22. プレゼンター ? プレゼンターの利点 – Application や ViewModel からプレゼンテーショ ンロジックを解放します。 – View と ViewModel は疎結合でお互いに交換可 能な状態に戻すことにより、再利用性を高め View や ViewModel をライブラリ化しやすくします。 – View と ViewModel と Model 全てにアクセス可 能な存在なので、アンドゥ?リドゥの実装場所に最 適です。 – ViewModel から View をクローズするメッセージ は必要なくなります。
  • 23. プレゼンター ? 親が子供を管理 – ダイアログ を表示させたいPresenterは ダイアロ グを管理するPresenterを生成して、ダイアログが 閉じたら解放します。 – パネルなどのコンテナを管理するPresenterは、 パネルの中身を管理するPresenterをパネル内に 表示するときに生成してパネルから削除されると きに解放します。
  • 25. プレゼンター ? WPFやSilverlightではこんな画面変化も可能 ですが、この場合はコンテナとなるパネルにス トーリーボードを仕掛けて RenderTransform の TranslateTransform を変化させて表示を 変えます。 ? 最初にA画面とB画面の View と ViewModel を用意してA画面を表示範囲内にB画面を表 示範囲外に設定してストーリーボードを起動し ます。
  • 26. プレゼンター ? MVVMパターンでは、 A画面とB画面の View と ViewModel を知っている何かの存在が必 要でコンテナの View で実行するとしたら、か なりの密結合になってしまったと思います。
  • 27. プレゼンター ? MVPVMパターンでは、 A画面のPresenterは A画面の View と ViewModel を知っていて、 B画面のPresenterはB画面の View と ViewModel を知っています、コンテナの Presenterはコンテナの View と ViewModel の他に、 A画面とB画面のPresenterを知って います。 ? 役割分担でき疎結合性も保たれます。
  • 28. まとめ ? MVPVMパターンはMVVM の能力と機能をす べて利用でき、 MVPの拡張性からプレゼン テーションロジックの複雑さにも対応できます。 ? MVPVMパターンは View と ViewModel は疎 結合でお互いに交換可能な状態に戻すのに 有効な手段です。 ? 皆さんも検討してみたらどうでしょうか?