楽水

人々の創造が自由に表現できる舞台づくり

デザインパターン

MVCとは【本来の仕組を詳しく解説】

投稿日:2020年12月15日 更新日:


今回は、

  • MVCって聞いたことがあるけど今ひとつわからないという方
  • アプリケーション開発でMVCをどう使うのか知りたい方
  • 最近、よく使われるMVVMの基本となる本来のMVCについて根本的に理解したいという方

を対象に、

  • MVCとは何か
  • MVCの仕組
  • MVCのメリット
  • MVCの現状

という観点で解説します。

MVCとは何か

MVCとはModel View Controllerの略で、ユーザーインターフェースを持つアプリケーションを実装するときのアーキテクチャパターンです。
アーキテクチャパターンとはデザインパターンの組み合わせから成り、アプリケーションアーキテクチャ(アプリケーションの設計思想および基本構造)を設計するときの問題と解法を集めたカタログのことです。
アーキテクチャパターンについては「ソフトウェアアーキテクチャ―ソフトウェア開発のためのパターン体系」という書籍が有名で、パターンの一つとして、MVCも紹介されています。

さて、MVCは、1979年、ゼロックス・パロアルト研究所のトリグヴェ・リーンスカウクによって、SmallTalk-80でWindowsアプリケーションを開発のための設計指針として考案されたものです。
しかし、複雑な構造を持つユーザーインターフェースを持つアプリケーションを実装するときの有用性からアーキテクチャパターンとして広く使われるようになりました。
GoFのデザインパターンとして知られている「オブジェクト指向における再利用のためのデザインパターン」という書籍にはMVCの役割について以下のように書かれています。

  • Modelオブジェクトはアプリケーションオブジェクト
  • Viewオブジェクトは画面の表現
  • Controllerオブジェクトはユーザー入力に対するユーザーインターフェースの働き


それでは、MVCの仕組について具体的に見ていきましょう。

MVCの仕組

本来のMVCパターンは、以下の3つのデザインパターンの組み合わせで構成されています。

  • Observerパターン
  • Compositeパターン
  • Strategyパターン


MVCの基本的な流れは次のようになります。

  1. ユーザーの入力をControllerが受ける。
  2. ControllerはModelを処理する。その際、必要に応じてModelのデータが更新される。
  3. Modelのデータが更新された場合、ModelはViewにそれを通知する。
  4. Viewは、Modelからの通知を受けて、Modelからデータを取得し、表示内容を更新後、ユーザーに出力する。

それでは、3つのデザインパターンを利用したMVCの仕組を一つ一つ見ていきましょう。

MVCの仕組1:Observerパターンの適用

まず、MVCの特徴の一つであるModelとViewの関係について説明します。
「オブジェクト指向における再利用のためのデザインパターン」には次のように書かれています。

  • MVCでは、ViewオブジェクトとModelオブジェクトの間に登録・通知に関するプロトコルを確立することで、これらを別々に扱っている。
  • ViewオブジェクトはModelオブジェクトの状態を反映することを保証しなければならない。
  • したがって、Modelオブジェクトのデータが変化すれば、Modelオブジェクトは必ずその旨をViewオブジェクトに通知して、それに応じて、Viewオブジェクトは自身の状態を更新する。
  • また、この方法では、さまざまな表現を提供しているために、一つのModelオブジェクトに複数のViewオブジェクトを割り付けることが可能となっている。
  • さらに、既存のModelオブジェクトを書き換えることなく、そのModelオブジェクトに対する新しいViewオブジェクトを生成することもできる。

この流れの一般的な仕組がObserverパターンです。

まず、Modelのattach操作で、ModelオブジェクトにViewオブジェクトを複数割り付けることができます。また、Viewは、Modelのdetach操作でModelオブジェクトから外すことができます。
Modelの状態が更新された場合、Modelのnotify操作によって、Modelに割り当てられているすべてのViewのupdate操作が実行されます。
なお、この図の場合、ModelとViewは親クラスになっており、それぞれ、具体的なConcreteModelとForm(フォーム画面)によって継承されています。
具体的ViewであるFormのupdate操作では、ConcreteModelの状態を取得して、自分の状態に反映する処理が行われます。
ここで、注意すべき点は、ModelはViewのインターフェースにアクセスしており、具体的なViewを知らない(この場合ConcreteModelはFormをしらない)ということです。
なので、Modelは自身の状態が更新されたら、具体的には知らない、自分に割り当てられているすべてのViewのupdate操作を粛々と実行するだけなのです。

Observerパターンによって、あるオブジェクトが状態を変えたとき、それに依存するすべてのオブジェクトに自動的にそのことが知らされ、それらをリアクティブに更新することができます(リアクティブプログラミング)。

MVCの仕組2:Compositeパターンの適用

MVCの次の特徴は、Compositeパターンを使ってViewオブジェクトがネストできるということです。

Compositeパターンの構造は、抽象的なクラス(この場合View)と、それを継承したComposite(複合物)とLeaf(葉:単体)から成っています。
さらに、Compositeは抽象的なViewを複数保持しています。抽象的なViewはViewのadd操作で追加され、remove操作で除かれます。
つまり、Compositeは、CompositeでもLeafでも持つことができるということです。
例えば、Compositeがフォルダー、Leafがファイルとすると、フォルダーはフォルダーでもファイルでも持つことができるということです。
Compositeパターンの場合、Composite全体に共通な操作を抽象的なクラスに定義し(この場合Viewのdraw)、CompositeとLeafが、それを実装します。
例えば、draw(表示)という操作をで言えば、Leafでは、自身を表示するように実装しますが、Compositeの場合、自身の表示だけでなく自分が保持しているすべての要素を表示するように実装します。
先ほどのフォルダーとファイルの例でいうと、フォルダーをコピーすると、フォルダー以下のすべての要素(フォルダーとファイル)もコピーされるということです。
上の図の場合、Leafの例としてButton(ボタン)やTextField(テキストフィールド)、Compositeの例としてFormをあげています。
なので、Formが表示されるとき、そこに含まれるすべての要素(ButtonやTextField)も表示されることになります。
ここで、注意すべき点は、Composite(この場合Form)は抽象的なViewのインターフェースにアクセスしており、自分が保持している具体的なView(例えば、ButtonやTextField)を知らないということです。
なので、この例の場合、Formは共通操作であるdraw操作を実施する上で、自分が保持している、具体的には知らないすべてのView(この場合ButtonやTextField)のdraw操作を粛々と実行するだけなのです。
Compositeパターンによって、個々のオブジェクトとオブジェクトの合成物を一様に扱うことができます。

MVCの仕組3:Strategyパターンの適用

次にMVCの3つ目の特徴、ViewとControllerの関係について説明します。
先ほどの例のとおり、Form、Button、TextFieldなどViewにはさまざまな種類があります。
なので、ButtonにはButton固有の入力処理、TextFieldにはTextField固有の入力処理があるというように、Viewの種類ごとに入力処理を定義する必要があります。
MVCでは、このような問題を解決するためにStrategyパターンを適用しています。

ユーザーに対する入力処理をprocess操作とすると、Controllerを継承したButtonControllerのprocess操作でButtonに対する入力処理を実装し、TextFieldControllerのprocess操作でTextFieldに対する入力処理を実装します。
Viewには抽象的なcreate操作が定義されており、Viewを継承したButtonのcreate操作ではButtonControllerが生成されてるよう実装され、Viewを継承したTextFieldのcreate操作ではTextFieldControllerが生成されるよう実装されています。
なので、ユーザーがButtonにアクセスしようとする場合、ButtonControllerが生成されButton固有の入力処理を実行するということになります。
このように、Strategyパターンでは、さまざまな処理のやり方(アルゴリズム)をStrategy(戦略)としてカプセル化し、必要に応じて、やり方を選択できるようにしています。
この例の場合、Viewの違いによるさまざまな入力処理のやり方をStrategyであるControllerにカプセル化した例になります。
なお、各Viewに対応したControllerを生成するcreate操作をFactoryMethodといい、これもFactoryMethodパターンというデザインパターンになります。

MVCのメリット

以上より、MVCのメリットは、一つのソフトウェアを
アプリケーション本来の処理(Model)
画面の表現(View)
ユーザーの入力処理(Controller)
に分けることによって次のようなメリットを得ることができると言えます。

  • Observerパターンを適用することで、Modelオブジェクトが状態を変えたとき、それに依存するすべてのViewオブジェクトに自動的にそのことが知らされ、それらをリアクティブに更新することができる(リアクティブプログラミング)
  • Compositeパターンを適用することで、単一のViewと複合的なViewを一様に扱うことができる
  • Strategyパターンを適用することで、各Viewに応じた入力処理をControllerにカプセル化し、必要に応じて選択できるようにできる

MVCの現状

システムアーキテクチャの変化による影響

MVCが生まれたのは1979年ですので、当時のMVCは、Windowsアプリケーションのようなスタンドアローンで動くアプリケーションを想定して考えられています。
なので、Modelオブジェクト、Viewオブジェクト、Controllerオブジェクトを比較的自由に結合することができるアーキテクチャになっています。
しかし、今日のように、クライアントサーバー型のアプリケーション、なかでもWebアプリケーションのようにMVC間にネットワークが介入する場合、それによる制約があり、本来のMVCをそのまま適用することが困難になってきました。
そこで、MVCから派生したMVC2やMVVMなどのアプリケーションアーキテクチャが登場してきたのです。

アプリケーションフレームワークによる影響

現在、プログラマーがWebアプリケーションを開発するときは、JavaのJavaEE、RubyのRuby on Railsなど、アプリケーションフレームワークをベースに開発するのが通常です。
このアプリケーションフレームワークにはMVCの派生であるMVC2が組み込まれているので、プログラマーが自らMVCのデザインパターンを適用してアプリケーションを開発する必要性はありません。
例えば、JavaEEの場合、Classに@Controllerというアノテーションをつけるだけで、それをControllerにすることができます。

以上、今回はMVCについて解説しました。

-デザインパターン
-,

執筆者:


  1. […] MVCについて詳しく知りたいかたは、 MVCとは【本来の仕組を詳しく解説】 を参照ください。 […]

  2. […] MVCについて詳しく知りたいかたは、 MVCとは【本来の仕組を詳しく解説】 を参照ください。 […]

関連記事

オブジェクトの性質【同一性、等価性、不変性、参照透過性】

ここでは、オブジェクトの性質について、以下の観点で解説します。 同一性 等価性 不変性 参照透過性 同一性と等価性 同一性と不変性 不変性と参照透過性 参照オブジェクトと値オブジェクト 参照型と値型 …

MVC vs MVVM

ここでは、MVCとMVC2の違いについて以下の観点で解説します。 MVCとは何か MVVMとは何か MVC vs MVVM MVCについて詳しく知りたいかたは、 MVCとは【本来の仕組を詳しく解説】 …

ソフトウェアの設計原則①SOLIDの原則

昨今の特徴を端的に表すと 個の時代 組織から個人へ。 心の時代 「もの」から「こと」へ。 ということになるのではないでしょうか。 激しく変化する多様な嗜好に合わせて、 ビジネスの変化が加速化 ビジネス …

ソフトウェアの設計原則②コマンド・クエリ分離の原則(CQS)

ソフトウェアの設計原則①:SOLIDの原則という記事で、変化に強いソフトウェアの代表的な特徴として以下をあげ、それを実現する、ソフトウェアの設計原則の一つ、SOLIDについて解説しました。 保守性が高 …

ドメイン駆動設計入門【DDDをわかりやすく解説】

突然ですが、エンジニアの皆さま、Javaで開発したWebアプリケーションの構成、このようになっていませんか? データとgetter/setterだけのオブジェクト(JavaBean) 画面のコントロー …