注: PoEAA, 14-1: Model-View-Controller をまとただけの記事です
UI の相互作用を 3 つの明確な役割に分割するパターンを「モデルビューコントローラ」とよぶ。
<img src="http://53ningen.com/wp-content/uploads/2015/12/mvc.png" mvc" width="410" height="240" class="aligncenter size-full wp-image-146" />
View と Controller は互いに依存してよい。View と Controller はそれぞれ、Model に依存してよい。
パターンの仕組み
モデルは UI に関わらない ドメインについてのデータやふるまいが表現されたオブジェクト。ビューは UI の中でモデルを表現する。ビューは情報の表示だけを責務として負う。コントローラは、ユーザーからの入力を受け取り、モデルを操作して、ビューを適切に更新する。このように UI はビューとコントローラの協調によって構成される。
プレゼンテーションとモデルの分離
根本的にプレゼンテーションとモデルは異なる関心事を持っている。ビューはどのように良い UI を提供するかということに興味があり、モデルはどんなロジックでデータを取り扱おうかということに関心がある。したがって分離を行い、各関心事に応じて構造化するために分離を行う。
非ビジュアルなオブジェクトは、ビジュアルなオブジェクトよりテストがしやすい。当たり前のことではあるが、プレゼンテーションとモデルを分離することにより、ドメインロジックのテストは容易になる。
プレゼンテーションはモデルに依存するが、モデルはプレゼンテーションに依存しないようにする。こうすることによりモデルを構成するときに、どんなプレゼンテーションから使われるかということを全く意識しなくてすむようになる。また、これによりモデルを利用して新たなプレゼンテーションを追加することが容易にもなる。
複数のウィンドウを持ったクライアントにおける問題
複数のウィンドウを持つリッチクライアントでは、あるモデルを参照する複数のプレゼンテーションが同時に表示される可能性がある。その際、ユーザーが1つのプレゼンテーションを更新したら、その変更は伝播されなければならない。モデルがプレゼンテーションに依存を作らずにこのようなことを実現するためには、オブザーバーパターンの実装が必要になる。プレゼンテーションはモデルのオブザーバーとして動作させ、モデルが変化するごとにイベントが発生して、情報が更新されるされる仕組みを実現する必要がある。
ビューとコントローラの分離
こちらは、プレゼンテーションとモデルの分離に比べると重要度は下がる。例えば、編集可能な振る舞いと編集不可能な振る舞いを同時にサポートをしたいときに、ビューとコントローラを分離したいといったモチベーションが生じる。1 つのビューに対して、2 つのコントローラを作ることにより対応できるが、通常はそのような分離は行われていない。
プラットフォームによっては UI における入力と出力はしばしば不可分であり、GUI フレームワークではビューとコントローラを組み合わせていることが多い。Web インターフェースではコントローラとビューの分離が行われることが多い。
パターンを用いるタイミング
モデルビューコントローラは、プレゼンテーションとモデルおよび、ビューとコントローラの分離に特徴がある。前者については非常に重要で、ほとんどの場合、分離をすべきである。後者についてはわりあい重要ではなく、必要なときにだけ分離をすることを推奨する。ネイティブクライアントにおいて、分離することはほとんどないが、ウェブフロントエンドにおいて、ビューとコントローラを分離することは珍しくない。
感想
モデルビューコントローラについては POSA を読まないとダメそうだ。正直 PoEAA の説明、わりと雑では?と思ってしまった。あと このあたり を読んでおきたい。
Pinned Articles
About
ウェブ界隈でエンジニアとして労働活動に励んでいる @gomi_ningen 個人のブログです
Tags
JavaScript
PowerShell
kibana
elasticsearch
fluentd
nginx
イベント
五十嵐裕美
村川梨衣
logrotate
IoT
Scala
Java
C言語
iputils
ICMP
WUG
mastodon
Swift
AWS
Clock
Windows
アーキテクチャ
PoEAA
iOS
DeviceFarm
プログラミング言語
OS
StepFunctions
Lambda
Serverless
terraform
ポエム
RHEL
ネットワーク
GraphQL
CloudWatch
Linux
Coreutils
network
nc
telnet
LinuxKernel
fpinscala
ELB
IAM
AppSync
EFS
Gradle
english