Cutting Edge
Web フォームと ASP.NET MVC を比較する
Dino Esposito
目次
ASP.NET Web フォームのメリット
Web フォームのデメリット
ASP.NET MVC のメリット
ASP.NET MVC のデメリット
正しい見方
ASP.NET の完璧なモデルについて
議論の余地がない事実
まとめ
動作している Microsoft ASP.NET を初めて目にしたのは 1999 年のことでした。Microsoft ASP.NET がまだ仮に ASP+ と呼ばれていた時代です。当時、Microsoft プラットフォームで Web アプリケーションをビルドすることは、多数の Active Server Pages (ASP) を組み立てることでした。
典型的な ASP ページは、HTML リテラルが複数のコード ブロックに散在している状態で、各コード ブロックでは、スクリプト コード (ほとんどの場合 VBScript) を使用して、ActiveX Data オブジェクト (ADO) フレームワークのコンポーネントなどの COM オブジェクトによって生成されたデータを組み込んでいました。1990 年代後半に導入された ASP.NET は、クライアントのブラウザーに表示される HTML の生成を洗練された方法で自動化できることを示した大きな進歩でした。
ASP.NET によって、さまざまな日常作業が簡略化され、さらに重要なことに、開発者は高い抽象レベルで作業ができるようになりました。その結果、開発者は Web ページの設計に関連するお決まりの作業に煩わされることなく、Web アプリケーションの中核をなす機能に注力できるようになります。
ASP.NET では、HTML や JavaScript に関する最低限のスキルがあれば、サーバー コントロールを基に、実用的な Web サイトやアプリケーションを作成できます。ASP.NET の本質は生産性が高いことです。この生産性は、ランタイムに統合された強力なツールと、サーバー コントロール、ユーザー コントロール、ポストバック イベント、ViewState、フォーム認証、組み込みオブジェクトなどの開発支援機能によって生み出されます。ASP.NET の基盤となるモデルは Web フォームと呼ばれるもので、Windows フォームのモデルに影響を受けているのは明らかです (Windows フォームは、Visual Basic の RAD (Rapid Application Development) の考え方に大きく影響されています)。
では、なぜマイクロソフトは "もう 1 つの" ASP.NET フレームワークである ASP.NET MVC をリリースしたのでしょう。今月のコラムでは、ASP.NET Web フォームと ASP.NET MVC のメリットとデメリットについて説明します。
ASP.NET Web フォームのメリット
前述のとおり、ASP.NET Web フォームは安定かつ成熟しており、多数のサードパーティ製コントロールやツールによって支えられています。
ASP.NET の急速な普及の鍵となった 1 つの考え方が、Windows デスクトップ開発から取り入れられたポイント アンド クリックであることは間違いありません。マイクロソフトは、Web フォームを使って、基本的に Visual Basic プログラミング モデルを Web に応用しています。ただし、デスクトップ開発がステートフルなのに対し、Web は本来ステートレスです。したがって、Web フォームのモデルでは、原則的に、さまざまな機能を抽象化することで、ステートフルなモデルのシミュレーションを Web 開発者に提供しています。その結果、HTML や JavaScript の知識が豊富な Web エキスパートでなくても、効果的な Web アプリケーションを作成できました。
Web 上でステートフルなプログラミングのシミュレーションを行うために、ASP.NET Web フォームでは、ViewState、ポストバックなどの機能と、全体的にイベント駆動型の考え方を導入しています。たとえば、開発者がボタンをダブルクリックすると、サーバーに対するユーザーのクリックを処理するコード スタブが自動的に生成されます。.NET 開発と、サーバー コントロールなどいくつかのアドホック コンポーネントのプログラミング インターフェイスについての基本的な知識さえあれば、ASP.NET Web アプリケーションの作成に取り掛かることができます。HTML をプログラムから生成するサーバー コントロールと、実行時パイプラインは、迅速な開発サイクルを実現するうえで非常に役立ちます。
結局は、ASP.NET Web フォームの主要機能は、ASP 関連の一部のベスト プラクティスを補完するものにすぎません。たとえば、ポストバック、入力フィールドの自動設定、ページ表示前の認証と承認、サーバー コントロール、ページのコンパイルは、ASP.NET Web フォームのために最初から考案および作成された機能ではありません。これらはすべて、ASP のベスト プラクティスから生まれました。10 年前、ASP 開発者 (私自身も含む) は、まさしく Web フォームが提供することになった一連の機能を求めていました。また、ASP.NET Web フォームでは、JavaScript、CSS、HTML という Web スタック全体の上に完全な抽象層が用意され、概して開発者の期待を上回るものでした。
ASP ページを作成するには、Web とスクリプト言語についての知識がかなり必要でした。それに対し、ASP.NET ページを作成するには、主に .NET とそのコンパイル型言語についての知識が必要です。生産性と、データ駆動型の基幹業務アプリケーションの迅速な開発は、ASP.NET Web フォームのセールス ポイントになっています。しかし、それはもう過去の話です。
Web フォームのデメリット
この不完全な世界に存在する多くのものと同様に、ASP.NET Web フォームにも問題はあります。長年の経験からすると、どう考えても、関心の分離 (SoC: Separation of Concerns) は本質的な部分で Web フォームの考え方となじむものではありません。
ASP.NET Web フォーム アプリケーションでは自動テストが困難です。これは、SoC となじまないことだけが理由ではありません。ASP.NET Web フォームは、ある程度は拡張可能なモノリシックなランタイム環境を基盤としていますが、プラグ可能で柔軟なシステムではありません。ランタイム全体を実行しないで、ASP.NET アプリケーションをテストすることはほぼ不可能です。
ステートフルなモデル実現するには、各サーバー ページの最新の既知の状態を非表示フィールド (ViewState) としてクライアント ページに埋め込みます。ViewState は Web フォームに問題がある例として頻繁に引き合いに出されますが、それほど悪者呼ばわりされる機能ではありません。実際、古い ASP で ViewState のような構造を使用することは、最先端のソリューションでした。ASP の観点では、ステートフルのシミュレーション (つまり、ポストバック、ViewState、コントロール) は偉大な成果でしたが、HTML や JavaScript の詳細から Web フォームが分離される方法についても、当初は同様に偉大な成果とされていました。
最近の Web ページでは、HTML の抽象化は、アクセシビリティ、ブラウザーの互換性、および jQuery、Dojo、PrototypeJS などのよく利用される JavaScript フレームワークとの統合の障害になるため、重大な問題となっています。既定では各ページがそのページ自体をポストする設定のポストバック モデルでは、ASP.NET ページが検索エンジンによって高く評価されることを難しくしています。検索エンジンやスパイダーでは、パラメーターが指定されているリンクの方が評価が高く、人間が判読できる文字列に推論できるとさらに評価が上がります。ポストバック モデルは、これとは間逆の動作です。また、過剰に大きな ViewState も、ランキングの基になるキーワードが ViewState の後、つまりドキュメントの先頭からかなり後ろに出現することになる可能性があるため、問題です。このような場合、エンジンによってはランクが低くなります。
ASP.NET MVC のメリット
Web フォーム モデルについて認識されている問題のいくつかは、ASP.NET 4.0 だけで解決できます。ViewState は無効にすることも、そのサイズを制御することもできます (このことに気が付いている開発者はほとんどいないようですが、ViewState のサイズは、はるかに効率的なシリアル化アルゴリズムが導入されたことで、ASP.NET 1.1 から ASP.NET 2.0 に移行する際に大幅に削減されています。ASP.NET 4.0 では、さらに効率よく ViewState を無効化および制御できる見込みです)。アドホックの HTTP モジュールを使用して URL の再書き込みを実行したり、さらには、ASP.NET 3.5 SP1 の最新の Web ルーティング API を使用したりできます。ASP.NET 4.0 では、スコープが指定される要素など、要素の ID を細かく制御できます。同様に、ASP.NET 4.0 では、より簡単で効果的に外部の JavaScript フレームワークと統合されるようになります。また、ASP.NET 3.5 SP1 の履歴管理 API によって、検索エンジンと相性のよいページを作成しながらも、AJAX とポストバックを連携できるようになりました。
いろいろな意味で、ASP.NET 4.0 の Web フォーム モデルは、前述の欠点のいくつかに対応した、より優れた環境です。では、ASP.NET MVC の意義は何でしょう。
ASP.NET MVC をわかりやすく紹介した記事が、MSDN Magazine 2008 年 3 月号に掲載されています (「Web フォームを使用しないで Web アプリケーションを作成する」)。この記事では、Chris Tavares が Web フォームを使用しない ASP.NET 開発の基本を説明しています。簡単に説明すると、ASP.NET MVC は、SoC と検証可能性を念頭に根本から設計し直された、ASP.NET アプリケーション作成のためのまったく新しいフレームワークです。ASP.NET MVC アプリケーションを作成するときは、コントローラーとビューを中心に考えます。まず、開発者が、ビューにデータを渡す方法と、コントローラーに中間層を公開する方法について決定します。コントローラーは、要求された URL と該当するデータを基に、表示するビューを選択します。各要求は、コントローラー クラスのメソッドを呼び出すことで、解決されます。ユーザー要求の対応に、ポストバックが必要になることはありません。ページの状態の保持に、ViewState が必要になることはありません。ブラウザーに渡す HTML を生成するために、内部処理がわからないサーバー コントロールは存在しません。
ASP.NET MVC を使用すると、ステートレスな動作、HTML のすべての要素の完全な制御、完全に自由なスクリプトと CSS という、Web の古きよき特徴を再発見できます。
ブラウザーに渡される HTML は、独立した置き換え可能なエンジンによって生成されます。ASPX の物理サーバー ファイルには、まったく依存しません。ASPX ファイルがまだプロジェクトに含まれている可能性はありますが、現在は、関連付けられている分離コード クラスと併せて、単純な HTML テンプレートとして機能します。既定のビュー エンジンは、Web フォームのレンダリング エンジンを基盤としていますが、nVelocity や XSLT など、その他のプラグ可能なエンジンも使用できます (詳細については、MVCContrib Web サイト (mvccontrib.codeplex.com、英語) を参照してください)。
ランタイム環境は、ASP.NET Web フォームと大部分が同じですが、要求サイクルはより単純かつ直接的になっています。Web フォーム モデルの不可欠な要素であるページ ライフサイクルは、ASP.NET MVC では必要ありません。ただし、ASP.NET MVC の既定のビュー エンジンは、やはり Web フォーム レンダリング エンジンを基盤としていることに注意してください。これは、マスター ページと一部のサーバー コントロールを ASP.NET MVC ビューでも使用できるようにするための処置です。ビュー エンジンが Web フォームを基盤とする限り、ビューは標準の分離コード クラスを使用した ASPX ファイルになります。このようなファイルでは、Init、Load、PreRender などの従来のイベントのほか、GridView コントロールの RowDataBound など、コントロール固有のイベントを処理できます。既定のビュー エンジンを無効にすると、標準のページ ライフサイクルの Page_Loador などのイベントは必要なくなります。図 1 は、Web フォームと ASP.NET MVC のランタイム スタックを比較しています。
図 1 ランタイム スタックの比較図 (クリックすると拡大画像が表示されます)
図 1 で "Page lifecycle" (ページ ライフサイクル) と書かれた四角形は、読みやすさを考慮して詳細を示していませんが、それぞれにいくつか追加のイベントが含まれます。とにかく、ASP.NET MVC のランタイム スタックはより簡潔になっています。この違いは、ページ ライフサイクルがないことによります。ただし、このために、ページ要求間でビジュアル要素の状態を保持することが難しくなります。状態は Session または Cache に保存できますが、どちらに保存するかの判断は開発者にゆだねられます。
図 2 は、ASP.NET MVC 要求のシーケンスを表しています。
図 2 ASP.NET MVC 要求のシーケンス図 (画像をクリックすると拡大表示されます)
MVC という略語は、Model-View-Controller (モデル ビュー コントローラー) を表します。ただし、図 2 に示されたパターンは、MVC パターンの従来の構成とは完全に一致しないことに注意してください。特に、MVC オリジナル資料では、オブザーバーの関係によって、モデルとビューが関係付けられています。しかし、MVC パターンは巧みに緩く定義されています。また、さらに重要なことに、MVC パターンは Web がまだ誕生していない時に考案されていることです。MVC が Web に取り入れられたことで、MVC は Model2 とも呼ばれる 図 2 のようなモデルへと変遷しました。一般に、MVC について見聞きする場合は、MVC とは呼ばれるものの微妙に異なるモデルが相当数あることに注意してください。
ASP.NET MVC のデメリット
このように、ASP.NET MVC によって、関心が適切に分離された理路整然とした設計、簡潔になったランタイム スタック、HTML の完全な制御、飛びぬけた拡張性、テスト駆動開発 (TDD) を、妨げるのではなく、実現する作業環境が現実のものになりました。では、ASP.NET MVC は Web 開発者にとって夢の楽園なのでしょうか。
Web フォームと同様に、人によっては明らかに ASP.NET MVC のメリットと思えるものが、デメリットと見なされる場合があります。たとえば、HTML、JavaScript、および CSS の完全な制御というのは、ASP.NET MVC では Web 要素を手動で入力することを意味します。ただし、この手間は、最近の JavaScript ライブラリとさらに異なるビュー エンジンを使用することで、軽減できます。しかし、概して、Web フォームには存在していた、HTML の生成を支援するコンポーネント モデルのようなものはありません。現在、HTML をより短時間で記述するために利用できるツールは、HTML ヘルパーとユーザー コントロールだけです。このため、ユーザービリティと生産性向上という意味では、ASP.NET MVC を後退したテクノロジと捉える ASP.NET 開発者もいます。ASP.NET MVC により日々の開発にもたらされた影響はありますが、MVC パターンについて事前の知識が必要なことも、指摘されるポイントです。ASP.NET 実装では、コントローラーとビューがどのように連携するかを認識しておく必要があります。つまり、ASP.NET MVC は、経験から簡単に習得できるようなものではありません。私の経験では、これが平均的な Web フォーム開発者の生産性を低下させる原因になる可能性があります。
正しい見方
アーキテクトまたは開発者にとって、Web フォームと ASP.NET MVC 間の構造的な違いを理解し、十分に考えられた決断をできるようにしておくことが非常に重要です。能力のあるチームはどちらを使用しても Web ソリューションを作成できるという意味では、概して、ASP.NET Web フォームと ASP.NET MVC は機能的には同等です。
ただし、チームのスキル、教育、および姿勢は、心に留めておくべき重要なポイントです。おのずとわかることだと思いますが、どちらのフレームワークでも、メリットとされている機能のほとんどはデメリットと見なされることがあり、その逆もまたしかりです。たとえば、HTML の完全な制御は、人によっては本当に便利な機能になる場合も、悪夢になる場合もあります。個人的には、ASP.NET MVC の複雑なビュー ページのコンテンツを初めて見たときは衝撃を受けました。しかし、まだかなりの数の ASP ページをアプリケーションに使用されていたお客様に同じページを見ていただいたところ、お客様はほっとされたのです。厳しい要件の 1 つがアクセシビリティであれば、表示される HTML を完全に制御したいと考えるでしょう。これは、Web フォームでは完全には実現できません。一方、非常にデータ駆動型のアプリケーションを作成していれば、Web フォームが提供する一連のデータ バインド コントロールやステートフル機能を便利に思うでしょう。
現在、マイクロソフトは ASP.NET MVC を ASP.NET Web フォームに代わるテクノロジとは位置付けていません。Web フォームは、Web アプリケーションに適したパターンであることは間違いありません。一方、Ruby-on-Rails によって、MVC も Web アプリケーションに適したパターンになり得ることが証明されており、ASP.NET MVC によってこれが実証されています。
結局、Web フォームにも ASP.NET MVC にも、さまざまなレベルで影響するメリット、デメリット、および構造的な違いがあります。概して、Web フォームは RAD の考え方を支持し、ASP.NET MVC は TDD 指向だと言えるでしょう。また、Web フォームは、ステートフルな環境のシミュレーションを行う Web の抽象化を目指していますが、ASP.NET MVC は Web 本来のステートレスを活かして、疎結合され検証可能であり、検索エンジンと相性がよく、HTML を完全に制御できるアプリケーションの作成に向いています。
ASP.NET の完璧なモデルについて
Web フォームを長年使用してきて、さまざまなデメリットに気が付きました。ASP.NET MVC は、つまり検証可能性、HTML の制御、関心の分離といった問題に、実にうまく対応しています。ただし、現時点では ASP.NET MVC を同程度に有効な選択肢として見ていますが、すべての Web アプリケーションに適した万能のテクノロジであると私は思いません。個人的な意見ですが、現在の ASP.NET MVC には、HTML の標準的な要素の作成するための、あるレベルの抽象化がありません。HITML ヘルパーは、HTML の作成にかかる時間の短縮を図った興味深い試みにすぎません。近い将来、Web フォーム サーバー コントロールと同じぐらい簡単にすぐに習得および使用でき、しかしポストバックおよび ViewState モデルとは完全に無縁の、新しい MVC 固有のサーバー コントロールが提供されることを願っています。希望としては、HTML テーブルを生成するループを記述する手間を省くことができながら、列のテンプレート、サーバー側のデータ バインド イベント、スタイル設定オプションがある System.Web.Mvc.GridView が提供されると嬉しいです。このような MVC の GridView と現在の Web フォームの GridView の違いは何でしょう。MVC の GridView は HTML と、必要に応じて行に固有の JavaScript を生成するだけで、ページ設定や並べ替えなどの処理は行いません。ページ設定や並べ替えは、他の特定のコントロールまたは開発者が作成した通常のリンクにゆだねられます。この方法であれば、MVC GridView により ASP.NET MVC である程度の RAD を実現でき、手動で作成されたページを排除することなく、ページの開発時間を短縮できます。
問題の源に戻ると、Web フォームと ASP.NET MVC の重要な違いは、基盤とするパターンです。Web ファームは "ページ コントローラー (Page Controller)" パターンに基づいたモデルです。Web フォームは UI を意識し、ページの概念を中心に成り立っています。つまり、ページが入力を取得し、ポストバックを行い、ブラウザーに対する出力を決定します。したがって、開発環境は、ウィザードや機能豊富なデザイナーなどを利用して、短時間でプロトタイプを作成できるように工夫されています。ユーザーの操作は、各ページの分離コード クラスのメソッド実行につながります。ただし、その時点では、適切な SoC の使用を妨げるものはなく、MVC やモデル ビュー プレゼンター (MVP: Model-View-Presenter)、さらにはモデル ビュー ビュー モデル (MVVM: Model-View-View-Model) などのパターンの適用を阻止するものも厳密にはありません。
Web フォームのアーキテクチャは、SoC を促進するものではありませんが、妨げるものでもありません。Web フォームのアーキテクチャでは、つい、コントロールのドラッグ アンド ドロップを利用し、直接イベント スタブにロジックのコードを含めてそれ以上の分離をせず、データベースに直接接続する UI と併せてデータ ソースを直接ページに埋め込みたくなります。Web フォームでの MVC の利用は禁止もされていませんし、邪魔になるものでもありません。ただ、Web フォームのインフラストラクチャの多くの部分を処理しなければならないため、MVC を実践する開発者がほとんどいないだけです。
しかし、検証可能性については、話が違います。ASP.NET Web フォームは、単体テストは可能ですが、そのためにはかなりの修練とスケルトン コードの作成が必要です。SoC を意識してコーディングする限り、プレゼンテーションとビジネス ロジックのテストと再利用が可能です。当然ながら、テスト プロジェクトを自動的に作成してくれる Visual Studio プロジェクト テンプレートはないと思います。フレームワークのテストとモック作成に精通し、テスト プロジェクトを自分で管理する必要があります。しかし、これは実行可能です。ただし、検証可能性という点では、本当の違いは Web フォームと ASP.NET MVC 間にあります。Web フォームでは、とにかく ASP.NET MVC の持つ柔軟性は得られません。これは正真正銘の制限です。ASP.NET MVC は検証可能性を考慮して設計されています。つまり、ASP.NET MVC のアーキテクチャでは、コンテキストから独立しているか、コントラクト インターフェイスから接続される、元来検証可能なコードを開発者が作成できるようになっています。さらに重要な点は、ASP.NET MVC の組み込みオブジェクトは、インターフェイスと基本クラスを公開するため、モックを利用できます。テストの観点では、Web フォームでできる最良の処理は、ロジックを別個の、簡単にテストできるクラスに移動することです。その後、HTTP 要求を送信し、結果を確認することで、プレゼンテーション (ASPX と分離コード) をテストします。ただし、ASP.NET ランタイム全体を実行しなくても、Web フォームでこのテストを実行できます。ASP.NET MVC では、テストの大半は、ビューに渡されるデータが正しいかどうかを確認することが目的です。また、組み込みオブジェクトのモックアップを作成し、完全に分離された環境でテストを実行できます。
また、ASP.NET MVC のメリットである HTML の制御と SEO に適した URL も、ある程度は Web フォームで実現可能なことにも注意してください。特に、ASP.NET 3.5 SP1 には、SEO 用の URL ルーティングおよび履歴 API が付属しています。一方、CSS アダプターは、Web フォームで HTML を制御するために利用するツールです。JavaScript および AJAX フレームワークとの統合は、実のところ、Web フォームの問題ではなくなりました。
議論の余地がない事実
ASP.NET Web フォームと ASP.NET MVC は、一方で他方を置き換えるという意味での競合技術ではありません。どちらかを選択する必要はありますが、アプリケーションが変われば、別の選択をしなければならない可能性があります。結局、旅に出るときに、車とオートバイのどちらにするかを決めるようなものです。旅ごとに選択をする必要があります。そして、両方の移動手段を利用できることは、問題ではなく、機会であると捉えるべきです。この 2 つのフレームワークには、次のような事実があります。
- Web フォームはテストしにくい。
- ASP.NET MVC では、開発者が、より詳細に HTML の生成を管理する必要がある。
- ASP.NET MVC は、ASP.NET で SoC を実現する唯一の手段ではない。
- Web フォームでは、作業を進めながら学習が可能。
- ViewState は、制御することも、無効にすることもできる。
- Web フォームは、Web のメカニズムを抽象化する設計。
- ASP.NET MVC は Web アーキテクチャを公開。
- ASP.NET MVC は検証可能性と、依存関係の注入を考慮して設計。
- ASP.NET MVC では、コードの設計が改善される。
- ASP.NET MVC は新しいテクノロジで、コンポーネント モデルがない。
- ASP.NET MVC は、Web フォームを否定するものではない。
ASP.NET MVC は、Web フォームを置き換えるのではなく、補完し合うものとして作成されました。ASP.NET MVC は、Web フォームのいくつかの弱点を、ASP.NET MVC 元来のメリットにしています。しかし、Web フォーム自体に十分なガイドは用意されていませんが、テスト、SoC、SEO、HTML の制御ができないなどの問題は、多少の修練と適切な設計により、Web フォームでも回避または縮小できます。
まとめ
Web フォームと ASP.NET MVC の両方にメリットとデメリットがあることを説明しました。しかし、ASP.NET MVC がアプリケーションで SoC と検証可能性を実現する唯一の手段であると見なし、多くの開発者は、ASP.NET MVC の方を利用しているようです。しかし、ASP.NET MVC は本当に唯一の手段でしょうか。そんなことはありません。ただし、ASP.NET MVC では、より簡単で自然に SoC を実現でき、テストもしやすいコードを記述できます。しかし、ASP.NET MVC を使用したところで、魔法のようにすべての開発者を熟練のアーキテクトに変えるわけでも、冗長でお粗末な設計のコードの作成が防止されるわけでもありません。結局、Web フォームも ASP.NET MVC も、複雑な現実世界のソリューションに効果的に対処できるように、設計および実装されるアプリケーションの作成に役立ちます。ソフトウェアの魔法などは存在せず、ASP.NET によってこれまでサポートされてもいません。
Dino に対するご意見やご質問は cutting@microsoft.com (英語) までお送りください。
Dino Esposito は、IDesign 社のアーキテクトであり、『Microsoft .NET:Architecting Applications for the Enterprise』(Microsoft Press、2008 年) の共著者です。Dino はイタリアに在住し、世界各国で開催される業界のイベントで頻繁に講演しています。ブログは weblogs.asp.net/despos (英語) で読むことができます。