結論
fluxのstoreは、(意味があって)「プレゼンテーションとドメインの分離」(PDS)に則っていないので、MVCのモデルではありません。
要約
MVCが考えられた時代では、プレゼンテーションロジックとドメインロジックが同等、もしくはドメインロジックの方が多かったです。その場合、PDSが有効でした。
現代のWebフロントエンドでは、プレゼンテーションロジックの方が圧倒的に多いです。プレゼンテーションロジックが9割ということも珍しくありません。この場合は、PDSは役に立ちません。
プレゼンテーションロジックの中で状態を持つ部分と、画面を描画する部分を分離する方が合理的に分割できます。この分離された「プレゼンテーションロジック中の状態を管理する部分」が「fluxのstore」です。
背景
以下の一連の議論を読んで、コンテキストに誤解がありそうなので、補完します。
blog.nkzn.info
nekogata.hatenablog.com
mizchi.hatenablog.com
本文
MVCが考えられた時代
Wikipediaの以下の記述を見ますと
1979年: パロアルト研究所にてTrygve Reenskaugが考案。[1][2]長い間、Smalltalk-80の実装のみが公開され、MVCに関する公開情報はなかった
MVCが考えられた時代は1979年頃のようです*1。
70〜80年代のアプリケーションの設計の話です。
Webアプリケーションはまだありません。
対象としているのはGUIアプリケーションです。
MVCは、Ruby on Rails等のWebサーバーアプリケーションでの設計にも活用されていますが、Webフロントエンドの話をする時に気にする必要はありません。
GUIアプリケーションといっても、現在のような複雑なプレゼンテーションは持っていません。
CUIに毛が生えたものと考えてください。
例えば、次の操作を想像してください。
- ユーザーは、GUIでパラメータを10個設定
- ユーザーは、実行ボタンを押す
- アプリケーションは、パラメータに基づいて計算をする(この間10分)
- アプリケーションは、結果を表示
複雑かつ重要なロジックは、3の部分にありこれをドメインロジックと呼んでいました。
それ以外の1, 2, 4は、記述は面倒さという意味の複雑さはありますが、重要度は低いです。
これをプレゼンテーションロジックと呼んでいました。
このような構成のアプリケーションには、 プレゼンテーションとドメインの分離 (PDS)が大変有効機能します。
ドメインロジックをプレゼンテーションロジックから分離することで、入念にテストしたり、GUIの代わりにCUIをつけて他の環境で実行したりできます。
さらにMVCでは「ユーザーの入力」に関わる部分をController、「画面の表示」に関わる部分をViewと分割します。
上記の操作の
- 1, 2がController
- 3がModel
- 4がView
と、綺麗に分割できました。
現代Webフロントエンドの複雑さ
現代のフロントエンドのもつプレゼンテーションロジックは遥かに複雑です。
ドメインロジックは変わらず単純です。
複雑なドメインロジックが必要な場合はサーバーで実行することが多いでしょう。
プレゼンテーションロジックは複雑です。
現代のアプリケーションでは、ユーザビリティを高めるためにユーザーの操作には即応することが可能であり、必要とされています。
例えば、ユーザーの操作に即座に反応してバリデーションの表示状態を変更します。
複数のパラメータから中間データのプレビューを作って表示するかもしれません。
次の操作をイメージしてください。
- ユーザーは、パラメータを変更する
- アプリケーションは、バリデーションを実行する
- アプリケーションは、バリデーション状態に変更があれば、バリデーション表示を更新する
- アプリケーションは、複数のパラメータから、プレビューデータを作る
- アプリケーションは、プレビューデータに変更があれば、プレビュー表示を更新する
これを何度も繰り返した上で、
- ユーザーは、保存ボタンを押す
- アプリケーションは、中間データをサーバに送る
このように、現代のWebフロントエンドのプレゼンテーションロジックは、MVC時代のプレゼンテーションロジックに比べて遥かに複雑です。
ユーザーの1操作ごとに、MVC時代のプレゼンテーションロジックと同等かそれ以上のロジックが実行されようなものです。
前述の操作のうち、どこがドメインロジックで、どこがプレゼンテーションロジックでしょうか?
- バリデーションはプレゼンテーションの状態を更新するので、プレゼンテーションロジックではないでしょうか?
- 中間データの生成ロジックも、プレビューデータを更新するので、プレゼンテーションロジックではないでしょうか?
「バリデーションはサーバーと同じロジックを実行するので、ドメインロジックだ」と考えることもできます。一方で、「データをサーバに送るのは、永続化層であってドメインロジックではない」という考え方もできます。
PDSが簡単な判断基準ではなくなっています。
また、アプリケーションごとにPDSを拡張したルールを作成し、プレゼンテーションロジックとドメインロジックに分けたとしましょう。
さらにMVCに分割してみましょう。
一部は流用できるかもしれませんが、入力パラメータのバリデーションは、入力パラメータごとに実行する必要があります。
結局、ユーザーの操作1つに対して1つのMVCのセットを作ります。
これが設計の助けになるかというと、なりません。
私の経験では、ユーザー操作ごとプレゼンテーションロジックとドメインロジックの境界が揺らぎ、綺麗なレイヤードアーキテクチャにはなりません。
修正する時は、1つのMVCセットごとに、「これはここではプレゼンテーションロジックだっけ?ドメインロジックだっけ?」と悩みながら修正する羽目になります。
設計は、本来、アプリケーションの抽象度を階層化して、全体のアーキテクチャと個々のロジックを別々に悩めるために行うはずです。
PDSを適用してこれでは、教条主義であり、現場の助けになりません。
PDSの放棄とプレゼンテーションモデル
PDSを放棄します。
プレゼンテーションロジックとドメインロジックを分けることをやめ、両者を含んだものをプレゼテーションモデルとして扱います。
以上が、MVP / MVVMなどのアーキテクチャが提唱される背景です*2。
結論
現代Webフロントエンドの複雑なプレゼンテーションにおいては、PDSに則ってアプリケーションを分割する意味が薄いです。
ですので、PDSに基づいているMVCのモデルは、現代Webフロントエンドの世界には居ません*3。
宣伝
以上の話を、ソースコードを交えて「現代Webフロントエンドデザインパターン」の「第11章 プレゼンテーションモデルパターン」に書きました。
ledsun.booth.pm
また、「Android アプリ設計パターン入門」では、プラットフォームはAndroidですが、以上のようなUIパターンの議論がとても綺麗に整理されています。一読の価値があります。