|
|
Modelの中身 ドメインロジックパターン 2012/8/4 わんくま同盟 大阪勉強会 #50 尾上雅則
1.Introduction 本セッションの目的と動機付け
Introduction –自己紹介 尾上 雅則 (おのうえ まさのり) 昭和58年生 フリーランス C#/MVVM WindowsForms/ASPNET/XAML系全般など Blog – the sea of fertility – http://ugaya40.net Twitter - @ugaya40 Facebook – http://facebook.com/ugaya40 MVVMer Microsoft MVP for Visual C#(2012/7~)
Introduction - 目的 本セッションの目的は、MVC系が分離しただけで未着手の領域 – Modelについてどういった実装の指針があるかを説明する事です。 この分野は用語の混乱がMVC系よりさらにひどく、正確な意味を把握するのが難しくなっています。
Introduction - 目的 世の中にはModelという言葉が溢れていますが、このセッションの終わりには MVC系のModel ≠ DDDのDomainModel DDDのDomainModel ≠ PoEAAのDomainModel Model ≠ PoEAAのDomainModel MVVMのViewModel≠MVCのViewModel MVCのModel ≠ MVVMのModel WPF MVVMのModel ≠ JS MVVMのModel のような事を特段説明せずとも理解していただけるようになっていただけている事、Model周りについての説明の混乱を避けられるようになる事目標としています。
Introduction –説明の方針 一般的なWebアプリケーションのMVC系のModelと、リッチクライアントのMVC系のModelを例にとって説明します。 今回はPDSの視点からModelを見て、それぞれASP.NET MVCとXAML MVVMを例にとりながらModelの中身について説明していく事にします。 前コマのセッションより、さらに先入観が理解の妨げとなる内容ですのでご注意ください。
2.PDSのDomain PresentationDomainSeparationのDomain部分再定義
2.PDSのドメイン PresentaionPlatformの都合が関係ある部分と、それ以外の部分にアプリケーションを責務分割する事。
2.PDSのドメイン アプリケーションはそもそもドメイン(問題領域)に対するソリューションである。 そしてそのうちの一部分をPresentationPlatformが便利に担ってくれている。 しかし便利に担ってくれている分、プレゼンテーションプラットフォームは固有の知識や事情を必要とする部分がある。そこを分離する
2.PDSのドメイン そしてPresentationPlatformの都合が関係ない部分とは、 ASP.NET MVCやXAML MVVMではそれぞれ、 基本的にSystem.WebやSystem.Windowsを必要としない部分になっているはずである。
2.PDSのドメイン これはすなわち、PresentationPlatformが異なれば、ASP.NET MVCのModel、XAML MVVMのModelの形も同じModelという名前にも関わらず異なる事を示します。 特にWebアプリケーションとリッチクライアントほどもPresentationPlatformの形が異なればほとんど共有は不可能です。
2.PDSのドメイン PDSから見たWeb MVCのModel Webアプリケーションは、極論「古いHTMLを受け取って新しいHTMLを返すメソッド」の様な動作です。(※最近流行りの非同期Web系は今回は説明の都合で無視します)
2.PDSのドメイン PDSから見たWeb MVCのModel セッション・ファイルアクセス・DB操作などの開発者自身がオブジェクトのライフサイクル制御をおこなわないような処理を外部サービスへのアクセス処理として考えると、 ここが開発者の 主な関心領域
2.PDSのドメイン PDSから見たWeb MVCのModel そしてそのすべてのオブジェクトが、1リクエストの度に生成され、そのリクエストの結果を返却次第破棄されるのがWebアプリケーションの特徴です。ステートレス(状態を持たない)です。
2.PDSのドメイン PDSから見たWeb MVCのModel PDSの視点を適用すれば、 Modelの役割は、 PresentationPlatformを使用してフィルタリングされたリクエスト/入力情報を元に、PresentationPlatformが新しい画面を描画するのに必要な情報を渡す役割 として定義できます。
2.PDSのドメイン PDSから見たWeb MVCのModel 必然的にModelのインターフェースは戻り値を持つメソッドで表現される
2.PDSのドメイン PDSから見たXAML MVVMのModel リッチクライアントアプリケーションにはWebのリクエストにあたるような明確な「オブジェクトとの生成と消滅のタイミング」の区切りが存在しないため、開発者がオブジェクトの生成消滅などのライフサイクルを管理しなくてはならない。(ステートフル)
2.PDSのドメイン PDSから見たXAML MVVMのModel また、WPFを除くすべてのXAML系(Silverlight/WindowsPhone/MetroStyleApps)ではネットワークアクセスなど、同期処理を提供するとUIスレッドのフリーズを招きかねない処理は非同期のみでしかAPIが提供されない。 例えばHttpWebRequestクラスには、 BeginGetResposeとEndGetResponseは存在するが、単なるGetResposeは存在しない。 少なくともXAML系では、時間のかかるメソッドはすべて非同期化するように流れが向いている。 この事がModelのインターフェースに与える影響は・・
2.PDSのドメイン PDSから見たXAML MVVMのModel Modelはすぐに戻り値を返せないので、 ユーザーからの入力をただ受け取るだけ。 ただModel内部では処理が始まっている。 ユーザーからの入力に際して・・
2.PDSのドメイン PDSから見たXAML MVVMのModel 時間のかかる処理の終了は、外部サービス(サーバなど)からのPush通知などと同じようにModel→ViewModel→Viewといった形で伝播される。 Modelへの入力と応答は切り離される事が多い!
2.PDSのドメイン PDSから見たXAML MVVMのModel PDSの視点を適用すれば、 Modelの役割は、 PresentationPlatformを使用してフィルタリングされたリクエスト/入力情報を受け取る。 のと、 自身の変化をPresentation層(ViewModel)に通知する事 として定義できます。
2.PDSのドメイン – まとめ PDSから見れば、同じ役割を担うアプリケーションでもMVC系のModelの役割はPresentationPlatformが異なれば当然違ってくる。 PresentaionPlatformが求めるMVC系のV + ○(C/P/VM)の責務は決定的でそれ以外の部分がModelとなるから。 Web MVCのModelとXAML MVVMのModelの形が違うのはそれぞれのPresentationPlatformの要求が異なるため。
3.ドメインロジックパターン PoEAA TransactionScript/ PoEAA DomainModel/ DDD DomainModel
3.ドメインロジックパターン Web MVCに求められるModelの形 Web MVCのModelは PresenPlatformに関連しない範囲で 要求情報を受け取って、画面の描画に必要な情報を返す。 それぞれ要求情報と、画面の描画に必要な情報とは何か?
3.ドメインロジックパターン Web MVCに求められるModelの形 この画面の場合 検索対象はWeb 検索結果は全言語 検索単語は”MVC” 要求情報
3.ドメインロジックパターン Web MVCに求められるModelの形 この画面の場合 各種検索結果のURL/タイトル/サムネイルなテキスト 関連広告のURL/タイトル/サムネイルなテキスト などなど・・たくさん 新画面の描画に必要な情報
3.ドメインロジックパターン Web MVCに求められるModelの形 メソッドシグネクチャは Public SearchResult Model.Search( SearchType.Web, Language.All, “MVC”); のようなイメージ。
3.ドメインロジックパターン Web MVCに求められるModelの形 SearchResultは のようなただのデータの入れ物。 メソッドを持ったりする必要はない → 次のリクエストではまたこのオブジェクトを1から作り直すので自身が変化したりする必要がない。
3.ドメインロジックパターン Web MVCに求められるModelの形 Searchメソッド内部ではSearchResultに必要な情報をDBなどから引っ張ってきて、SearchResultを作る。 Web MVCのModelは多くの場合は、ユースケース中心粒度を基準に画面表示に必要なデータの入れ物を作成し返す。 この形が TransactionScriptパターンです。 PoEAAにあるドメインロジックパターンの一つです。 ASP.NET MVCではこの入れ物の事をViewModelと呼びます。
3.ドメインロジックパターン XAML MVVMに求められるModelの形 XAML MVVMではModelへのリクエストと、応答が分割される事が多いところまで説明しました。 Twitterクライアントアプリケーションを例に、XAML MVVMでのModelを説明します。
3.ドメインロジックパターン XAML MVVMに求められるModelの形 デモアプリ WPF4 Silverlight4 Windows Phone 7.1
3.ドメインロジックパターン XAML MVVMに求められるModelの形 Modelの構造 赤枠は変更通知コレクション
3.ドメインロジックパターン XAML MVVMに求められるModelの形 メインタイムラインを更新する Void TwitterApplication.Current.TimeLines[“Home”].Update() Staticプロパティ 内部ではネットワークアクセスが非同期で始まります。
3.ドメインロジックパターン XAML MVVMに求められるModelの形 メインタイムラインを更新する 内部での非同期処理が終了すると、タイムラインの変更通知コレクションに新しいTweetが追加されます。 この変更通知がこのModelから →ViewModel →View へと伝播していくわけです。
3.ドメインロジックパターン XAML MVVMに求められるModelの形 今回のデモアプリでは、Modelの中のオブジェクトは一度作成されたら消滅はしませんが、実際にはツイート保持数があまりにも増えた場合は自身のコレクションを削除する処理もあり得るかもしれません。 その場合もModelの変更通知コレクションの変化がViewModel→Viewへと伝播していきます。 WebのTransactionScriptと比べると教科書通りのOOPです。 この形でのModelはコンソールアプリケーションでラップする形でも簡単にすべての機能を試せます。 (実際開発中デバッグはそうやって行いました)
3.ドメインロジックパターン XAML MVVMに求められるModelの形 画面に表示される情報は、Modelが保持する情報の射影であり、その状態は常に変化しうるし、その変化をPresentation層に伝達する手段を持つ。また教科書的なOOPのため、オブジェクト自身が自身に関するメソッドを持つ。 (WebのTransactionScriptの方がむしろOOP的に不自然) アプリケーションの振る舞いをOOPで表現しただけ この形の事をPoEAAでいうドメインモデルパターン と認識しています。 やはりドメインロジックパターンの一つです。 トランザクションスクリプトが特殊だからこその存在だと思います。
3.ドメインロジックパターン TransactionScript の問題 TransactionScriptをリッチクライアントに適用するとどうなるでしょう? 画面に表示されている情報はModelに保持されている情報の射影ではなく、ユースケースに基づいて作成された使い捨ての表示用オブジェクトです。 詳細画面での変更が一覧画面をリロードするまで伝わりませんね。
3.ドメインロジックパターン TransactionScript の問題 TransactionScriptは基本的にユースケース粒度の表示用データを集中して作っていくものなので、 例えば仕様変更などで、あるユースケースへの変更が別のユースケースに影響を及ぼす場合でもそれを認識できません/しにくいです。 所蔵本一覧取得画面の表示では、 本の価格は税込みを使うように変更 本当は所蔵本詳細画面でも同様の変更を行う必要があるが気づきにくい
3.ドメインロジックパターン TransactionScript の問題 あらゆる意味で変更に対する追跡性が低いのがTransactionScriptのデメリットです。 また、処理の起点はユースケースであり、サーバからのPush通知などを受け取るのはポーリングなどをしないと難しくなります。 しかしWebアプリではほとんど問題が出ない手法です。というか、まさにWebアプリケーションのための手法だと思います。Webアプリケーションはもともと処理の起点がユースケースしかありません。
3.ドメインロジックパターン DomainModel の問題 DomainModelをWebアプリケーションに適用しようとするとどうでしょう? ところがWebアプリケーションは結局TransactionScript的なインターフェースを必要とします。 また内部に作ったDomainModelもWebアプリケーションでは状態を持てないし、所属するメソッドをその入れ物に置くことは難しくなります。意義が薄くなり手間が増えますが・・・超大規模/DDD的な開発手法に限れば意味が出てきます。
3.ドメインロジックパターン おまけ)DDDのDomainModel ドメイン駆動設計(DDD)でのDomainModelはPoEAAのDomainModelとは意味合いが変わってきます。 DDDにおけるDomainModelとは 業務のドメイン(問題領域)の専門家とDomainModelを定義し、それを開発者も共有する。ドメインの専門家と作成したDomainModelをベースに開発を行う。 私の理解ではこんなところです。
3.ドメインロジックパターン おまけ)DDDのDomainModel DDDについての深入りはボロが出るので避けたいところですが、これはWebアプリケーション・リッチクライアント問わず想定されている開発手法です。 DDDのDomainModelは業務的な意味をモデリングしたのものであり、それがそのままオブジェクトであるだとかクラス構造であるだとかと必ずしも紐づけさせる必要がないものだと思っています。(もちろん紐づけた方が楽ですがWebじゃ厳しいですよね)
3.ドメインロジックパターン おまけ)DDDのDomainModel 業務的な意味を持つDomainModelは状態をもつだろうし、変化する事もあるでしょう。 IBMさんなんかはステートレスなはずなWebアプリケーションで擬似的にステートフルなDomainModelをオブジェクトして扱えるようにする製品を出しています。(成功例は知らないですが) そこまでしてDDD のDomainModelに拘る理由はなんでしょう?
3.ドメインロジックパターン おまけ)DDDのDomainModel 業務と、業務関連の状態の変化をそのまま図示しようとすると模造紙数枚をつなぎ合わせなければいけないような例えば金融のような超巨大業務ではTransactionScriptの変更追跡性の無さが致命傷となる場合があるからではないでしょうか? DDD の DomainModelに対する変更はTransactionScriptに対する変更よりはるかに追跡用意なはずです。 私の理解はこうですが、DDDに対する理解が浅いのでさまざまなご意見をお待ちしております。
3.ドメインロジックパターン おまけ)DDDのDomainModel 少なくともPoEAAにおいて、TransactionScriptと対になるDomainModelはアプリケーションの振る舞いをOOPしただけのものであり、DDDで言うDomainModelほどの業務的に深い意味と必ずしも紐づく必要はないはずです。 そうでなければTransactionScriptと粒度が異なってきます。 PoEAAのドメインロジックパターン(DomainModel/TransactionScript/未説明のTableModule)でのオブジェクトは画面に表示するデータの作り方と成り立ちに関わるものです。
3.ドメインロジックパターン-まとめ WebMVCのModelではステートレスなアプリケーションと相性の良いユースケース中心に使い捨ての表示用オブジェクトを組み立てるPoEAAでいう所のTransactionScriptが基本 リッチクライアントのMVVMでのModelではオブジェクト自身が状態や振る舞いを持ち、画面に表示される情報はそのModelが保持する状態の射影となるPoEAAでいう所のDomainModelが基本
4.まとめ PDSとMVC系とドメインロジックパターン PoEAA TransactionScript/ PoEAA DomainModel/ DDD DomainModel
4.まとめ PDSとMVC系のModel MVC系のModelとは、PDSの考え方によってアプリケーション全体からPresentationPlatformの知識を必要とする部分を除いた部分全て。 PresentationPlatformの形が変われば、同じ要件を実現するアプリケーション同士でもModelの形が変わってくる。
4.まとめ MVC系のModelとドメインロジックパターン Web MVCのModelはステートレスであるため、TransactionScript的なインターフェースを必要とする。 リッチクライアント – 特にXAML MVVMのModelはそのメソッドが戻り値を返しにくいなどの事情からDomainModelとしてしか設計しづらい。 ドメインロジックパターンはModelの中の設計指針の一つである。
4.まとめ 確認 MVC系のModel ≠ DDDのDomainModel DDDのDomainModel ≠ PoEAAのDomainModel MVC系のModel ≠ PoEAAのDomainModel MVVMのViewModel≠MVCのViewModel MVCのModel ≠ MVVMのModel WPF MVVMのModel ≠ JS MVVMのModel
ご清聴ありがとうございました!
Summary: 8/4 わんくま同盟大阪勉強会資料
| URL: |
No comments posted yet
Comments