前エントリーに引き続き、MVCパターンについて、その利点と、何が崩れるとそれが失われるかを考えてみる。以下、一部に図1-1、図1-2には無いV-C間の関連が前提になっている記述があるが、それについては次のエントリーで説明する。
- Viewの追加/変更がViewクラスに閉じ、Modelに影響しない
- ModelはView/Controllerへの依存が無く、安定度を上げることができる
- ModelとViewとをそのままにして、Controllerを差し替えることができる
- ModelはViewの表示状態に関係なく動作することができる
- Model+ControllerとViewを並列実行することができる
元々、ControllerはViewとModelとを繋ぐ役割で小規模だと考えられており、Viewの変更がControllerに影響することについては論じられることが少ないが、Controllerが肥大し、変更が入りにくいロジックを含むようになって、しかもControllerがViewに依存するようになると、Viewの変更の影響が変更されにくいクラスに及ぶようになり、この第1の目的に合わなくなる。
(2)は、Modelの品質は特に重要であることが前提にあり、できるだけ他への依存を無くし、個別に重点的にテストして、変更されにくいコードとして確立することを目的とした結果である。もちろんViewやControllerもきっちりテストしてバグの少ないのものに仕上げるべきであるが、ソフトウェアのバグを完全に無くすのは確率的に不可能であることを理解し、特に重点的に品質確保するコードの範囲を選択して絞るのは、現実世界では絶対に必要なことである。
一般に、自パッケージからの依存数をCa、他のパッケージへの依存数をCeとした時にCe/(Ca+Ce)と計算される、クラスの不安定度(Instability)は、0か1に近い方が良いとされるが、M,V,Cそれぞれをパッケージとして、Model内のクラスの不安定度をほぼ0(ViewのObserver I/F以外には外部パッケージへの依存が無い)にできるのがMVCパターンのメリットである。ModelがViewに依存するようになって安定度が下がったり、Controllerに安定度が高いクラスが混ざってController全体の安定度が中途半端になると、このメリットが損なわれることになる。
(3)は、ビジネスロジックやドメインモデルをユーザーインターフェースから分離することによって、ビジネスロジックやドメインモデルに対する同じ操作を複数のUIから実行できる(例えば、キー入力でもマウス入力でも同じ操作が実行できる、異なるメニュー画面から同じ操作が実行できるなど)構成がスムーズに実装できることを意味する。当然、MVCパターンはUIが複数あるソフトウェアを対象にしていることになる。
この利点により、ControllerをModelのテスト用のUIまたはテストコードに置き換えることによって、Modelを全く変更せずにテストすることが可能になる。GUIを持つアプリケーションにテスト用のCUIを追加したり、Modelに対して連続してメッセージ送信する自動テストプログラムを追加することも可能である。
プログラマーの長年の経験則として、結局ソフトウェア開発はいかに効率よくテストすることを可能にするかに掛かっている、というのがあり、特にここ10年くらいの流れである。テストドリブン開発やxUnitフレームワークが邪道だと否定される様子はほとんど無い。テストさえすりゃ作りはどうでもいい、ということに繋がる考え方でうまく行く筈が無いだろう、と、まともな科学者や技術者ならそう考えるものだが、現場は感覚的にも実際にも、ある程度以上きちんと作るのは困難になるので、限界を追求すると、きちんと作るよりきちんとテストすることにコストを掛ける方が成功するのが、人間の知力の限界を物語る現実なのである。
(4)は、計算処理中に表示処理を混ぜることがいかにプログラムを保守しにくくしてきたかを多くの人が思い知った結果であり、MVCパターンに限らず、データとプレゼンテーションを分離することは、よくなされることである。
データ及びそれに対する操作(business logic)に比べ、データの表現手段(presentation logic)はよく変更されるので、business logic内に表示用の処理が混ざっているとプログラマーはよく嫌な思いをする、ということもあるが、その前に、business logicとpresentation logicは品質確保の要件や要求レベルが異なることが多いのである。
(5)は、やはりビジネスロジックと表示系に要求される品質が異なる前提が根底にあるために利点と言えるものであり、表示系がメインのシステムでない限りは、出力先が人間である表示系の動作速度は比較的クリティカルではないので、動作速度が問題になると、自然に表示系をビジネスロジックとは非同期に優先度を下げて動作させようということになる。
逆に言うと、MVCパターンは表示系に求められる性能が高い、表示系に対する要求がクリティカルなシステムには適さない可能性がある。極端に考えると、例えば映像効果のためのシステムでは、表示デバイスの制御が問題の中心であり、映像が最終的な出力なので、映像出力系がModel、目的の映像出力を得るためのUIの表示系がViewだと設計することが考えられる。なので、もしUIに表示効果バリバリのフレームレートの高い描画が求められると、その描画系はViewではなくModelとして扱う必要が出てくることになり、本来のModelとViewのためのModelと、2つのModelが現れることになる。その2つのModelの調停をどこが担うか(Controllerが担うか、それら2つのModelを統括するMagager Modelを作るか)という問題もあるし、そもそも変更が入り易いUIをModelから分離するという目的に反してしまう問題がある。
コメント