アプリケーションのフロントエンドは次第に複雑になってきており、Ajax の問題を解決するにはクライアント・サイドの MVC JavaScript フレームワークを利用するのが有効です。しかしフレームワークは非常に種類が多いため、どれを選べばよいかわからないかもしれません。この記事では、最もよく使用されているフレームワークのなかから、Backbone.js、Spine.js、Knockout.js、Batman.js の概要を簡単に説明します。皆さんの次のプロジェクトのために、適切なフレームワークを選択する方法を学びましょう。

Peter Bell, Senior VP of Engineering, General Assembly

Peter BellPeter Bell は、技術、デザイン、ビジネスのためのキャンパス、General Assembly 社の技術部門の Senior VP であり、シニア・フェローです。彼は JavaScript、ドメイン特化言語、アジャイル・アーキテクチャー、NoSQL、要件と見積もりなどに関して世界中で講演を行い、幅広く著作活動を行っています。彼がこれまでさまざまなカンファレンスで講演を行っており、一例としては DLD Conference、ooPSLA、RubyNation、Code Generation、British Computer Society Software Practices Advancement Conference、Rich Web Experience などがあります。彼の記事は IEEE Software、Dr. Dobbs、IBM developerWorks、Information Week、GroovyMag に公開されています。



2012年 7月 12日

はじめに

15 年前、私達の多くは Perl や ColdFusion などを使用して Web サイトを作成していました。私達が作成していたスクリプトは多くの場合、スクリプトの先頭でデータベースに対してクエリーを実行し、取得したデータに必要な変換を適用し、同じスクリプトの最後でそのデータを表示するものでした。そうしたアーキテクチャーは単純な連絡先フォームを Web サイトに追加するには十分でしたが、アプリケーションが複雑になってくると、その方法ではスケーラビリティーがないため、複雑さに対処することができませんでした。しかし今や、ほとんどの Web アプリケーションは MVC (Model-View-Controller) アーキテクチャーで標準化され、ビジネス・ロジック、表示ロジック、ユーザーとの対話 (ルーティング) ロジックを別々のコードで処理するようになっており、Spring MVC から Rails に至るまで、MVC ベースの Web アプリケーションを短時間で実装するためのフレームワークが大量に生まれました。

頻繁に使用される略語

  • JSON: JavaScript Object Notation
  • MVC: Model-View-Controller
  • REST: REpresentational State Transfer

数年前に遡ると、クライアント・サイドの JavaScript アプリケーションを作成するためのライブラリーとして jQuery が主流になりつつありました。しかしアプリケーションの JavaScript が複雑になるにつれ、jQuery は複雑さに対処する上で必要ではあっても不十分なものになりました。例えば、単一ページの ToDo リスト・アプリケーションに、「緊急の ToDo」のリスト、「すべての ToDo」のリスト、「今日の ToDo」のリスト、「期限を過ぎている ToDo」のリストを含められる場合に、1 つの ToDo を削除するとどうなるでしょう?そのタスクが緊急で期限を過ぎている場合、ビューの中の 3 つか 4 つの異なる場所からそのタスクを削除するためのコードを作成する必要があるかもしれません。ある 1 つのオブジェクトを削除することにより、画面上に表示されている他の関連オブジェクトも削除または変更する必要がある場合、その複雑さは手に負えなくなる可能性があります。

クライアント MVC フレームワークはそうした問題を解決するために設計されたものであり、大半のクライアント MVC フレームワークは十分役立ちます。しかし、どのフレームワークを使用するのかを、どのようにして決めればよいのでしょう? JavaScript によるクライアント・サイドの MVC フレームワークはたくさんあります。この記事では、最もよく使用されているフレームワークのいくつかについて、大まかな概要を説明します。使用状況に合わせて適切なフレームワークを選択する方法を学びましょう。


Backbone.js

採用される頻度の点では、Backbone.js は他を圧倒して最もよく使用されているクライアント MVC フレームワークです。Backbone.js は多くのコミュニティーで使用されています。特に Rails 開発者に広く採用されており、Rails に関するコンサルティングで大変評判の良い thoughtbot という会社が提供している Backbone.js on Rails のような人気のリソースもあります。Backbone.js の強みは、REST (Representational State Transfer) ful な Web サービスとうまく統合できることです。RESTful な JSON (JavaScript Object Notation) モデルをバックエンド・データに使用し、Backbone.js で想定されている規約 (Rails で使用される規約に対応します) に従う場合、コードを作成しなくても Backbone.js をサーバーに接続することができるため、大幅に時間を節約することができます。

Backbone.js の場合、アプリケーションを構成する要素は、コレクション (複数のユーザーまたは記事)、モデル (1 人のユーザーまたは 1 つの記事)、ビュー、そしてルーターです。Backbone.js のビューは厳しい規則に従うものではないため、任意のテンプレート作成用またはレンダリング用 JavaScript フレームワークを使用することができます。ルーターは、Rails スタイルのルーターと従来の MVC コントローラーを組み合わせたものであり、指定された URL からリソースを取得し、どのコードを実行するのかを Backbone.js に指示します。リスト 1 は Backbone.js のルーターのコードの例です。

リスト 1. Backbone.js のルーターのコードの例
var Workspace = Backbone.Router.extend({

  routes: {
    "help":                 "help",    // #help
    "search/:query":        "search",  // #search/kiwis
    "search/:query/p:page": "search"   // #search/kiwis/p7
  },

  help: function() {
    ...
  },

  search: function(query, page) {
    ...
  }
});

Backbone.js には Underscore.js が含まれています。Underscore.js は関数型のスタイルで JavaScript を容易に作成するためのユーティリティー・セットであり、広範に及ぶコレクション・ベースの便利な処理をサポートしています。また Backbone.js には、ページのナビゲーションをスマートに処理するための Backbone.history も含まれています。

Backbone.js を使用することによる一番のメリットは、自動的にサーバーと統合されることです。それが皆さんにとって好都合な場合には、Backbone.js の扱い方を学ぶ価値があるかもしれません。フレームワークによっては 1 時間か 2 時間で使い始められるようになるものもありますが、Backbone.js の場合には、基本事項を学ぶだけでもおそらく 1 日か 2 日はかかります。そのため、Backbone.js は少なくとも 2、3 週間は携わることになる大きめのプロジェクトに向いています。

それでも、Backbone.js は完全なソリューションではありません。起こり得るメモリー・リークなどの問題に対処するために、おそらくかなりの量のコードを作成する必要があります。また、ニーズを満たすものが得られるようになるには、ビューの描画方法を何通りか試す必要があるかもしれません。


Spine.js

Spine.js はよく Backbone.js と比較されます。Spine.js は Backbone.js の影響を受けており、採用される頻度も Backbone.js と同程度です。Spine.js には、クラス、モデル、コントローラー、ビューがあり、この点は Backbone.js で導入されたコレクションに比べると、やや昔ながらのモデルに従っています。

Spine.js は CoffeeScript (「参考文献」を参照) で作成されているため簡潔であり、また (私の意見では) ソースが読みやすくなっています。Spine.js の動作を理解するためには CoffeeScript を理解する必要があります。ただし Spine.js アプリケーションを CoffeeScript で作成する必要はありません。それでも CoffeeScript で作成すると、クラスをはじめとする CoffeeScript の機能を利用することができます。JavaScript では従来の継承ではなくプロトタイプ・ベースの継承が使用され、JavaScript ネイティブではクラスがサポートされていません。CoffeeScript は極めて標準的なパターンをいくつか使用しており、それらのパターンを使用したい開発者のためにクラスを提供しています。単純な JavaScript で Spine.js アプリケーションを作成している場合には、単純に Spine.Class: var Users = Spine.Class.sub(); のように指定することで、CoffeeScript でコードを作成しなくてもクラスを利用できるようになります。

Spine.js のモデル、コントローラー、ビューはクラスを使用して実装されるため、クラスのメソッドとインスタンスのメソッドの両方を作成することができます。モデルにはビジネス・ロジックを処理する役割があり、モジュールの形をしていることから、拡張することができます。また、他のモジュールをそのプロパティーや関数を再利用して混在させる形で含めることもできます。モデルは、JSON へのシリアライズを自動的に行うことで、単にローカル・ストレージを使用して永続化することも、Ajax (Asynchronous JavaScript + XML) を使用することで、サーバーにオブジェクトを永続化することもできます。Backbone.js と同様、現在の Spine.js は Ajax を使用して永続化する実用的な方法がデフォルトになっています。ただし、必要に応じて独自のカスタム実装を作成するのも容易です。リスト 2 は Spine.js アプリケーションから引用した CoffeeScript コードの例です。

リスト2. Spine.js アプリケーションから引用した CoffeeScript コードの例
class Contact extends Spine.Model
  @configure "Contact", "first_name", "last_name"

  @filter: (query) -> 
    @select (c) -> 
      c.first_name.indexOf(query) is not -1

  fullName: -> [@first_name, @last_name].join(' ')

Spine.js と Backbone.js との間の最も重要な違いはサーバーとのやり取りの方法です。Backbone.js はサーバーでの処理を待ってから応答を表示するため、ある要素を削除、挿入、更新しようとすると、その処理が正常に完了するまでユーザー・インターフェース (UI) は更新されません。一方、Spine.js では即座に UI を更新することが重視され、サーバーとの Ajax はバックグラウンド・プロセスとして処理されます。この 2 つのフレームワークは洗練されているため、よく使用されており、ドキュメントも十分ですが、いずれか一方を選択しようとする場合、この更新方法が実用面でも考え方の面でも大きく異なる点です。

クライアント・サイドのエクスペリエンスの作成に一番の重点を置いている場合で、サーバーの状態の更新の重要度が二次的な場合には、Spine.js がより良い選択肢になるかもしれません。一方、主に状態変更が有効であったかどうかを確認するためにサーバーを使用している場合には、Backbone.js の方がより適しているかもしれません。UI の応答性は Spine.js を使用した方がよくなります。しかし Spine.js を使用して、ある要素の削除が成功したと表示されたものの、その要素を他の誰かが使用中のため削除できない、という応答がサーバーから送信された場合にはどうなるのでしょう?そのための対策はありますが、一般に Spine.js がより適しているのは、ユーザーが他のユーザーとデータを共有せず、そのユーザーが所有するデータに対して処理を行う場合です。例えば、Spine.js の一般的な使用事例としてショッピング・カートがあります。ショッピング・カートでは、検証に関する制約をすべてクライアント・サイドで処理することができます。


Knockout.js

ここまでで説明したツールが MVC 本来の意味で、真の MVC フレームワークなのかどうかは議論の余地があるかもしれません。Knockout.js は明らかに、従来の MVC ではなく、MVVM (Model-View-View Model) を実装しています。ただし、そのことを判断材料してはなりません。フレームワークを選択する際には、こうした頭字語で表されるモデルや分類に注目するのではなく、提供される機能に注目する方がはるかに重要です。

Knockout.js は MVVM モデルを理解している Microsoft .NET 開発者の間で特によく使用されています。どのようにしてビューに対してモデルの状態を宣言型でバインドするかが解決すべき一番の問題であるようなさまざまな状況で、Knockout.js は最高の選択肢となります。先ほど触れた ToDo アプリケーションの例には、Knockout.js が実によく適しているかもしれません。このアプリケーションでは、同じ ToDo マスター・リストのサブセットごとに数種類の異なるビューがあるため、ある 1 つの ToDo 項目が削除された場合はすべてのビューを更新する必要があります。

Knockout.js ではモデル、ビュー・モデル、そしてビューを作成します。Spine.js や Backbone.js の場合と同様、モデルの役割はビジネス・ロジック、検証、リモート・サーバーとやり取りする Ajax などの処理を行うことです (単にローカル・アプリケーションを作成しているのではない、という前提です)。ビュー・モデルのコードはモデル・データを保持し、モデル・データに対する処理を行います。例えば、ビュー・モデルにはリストの項目の追加、編集、削除の手段が含まれているかもしれません。ビュー・モデルと最も近い関係にあるのは従来の MVC アーキテクチャーのコントローラーです。ビューは情報を画面上に表現するためのマークアップを含むテンプレートです。Knockout.js では、ビューは宣言型でビュー・モデルにバインドされます (そのため Knockout.js を容易に使い始めることができます)。ワークショップの一部の生徒は約 1 時間で Knockout.js を使えるようになり、それほど単純ではないアプリケーションを 3 時間で構築することができます。

一般に、Knockout.js は小規模で単純なプロジェクトに適しています。大規模で複雑なプロジェクトには Backbone.js や Spine.js が選択される傾向があります。しかし、そうは言っても、経験豊富な Knockout.js 開発者であれば、保守が容易であるにもかかわらず高度な機能を持ったアプリケーションを作成することができます。Knockout.js を検討する場合には、比較的軽量のフレームワークで容易に取りかかれる Angular.js や Sammy.js (「参考文献」を参照) も同時に検討する必要があります。


Batman.js

Batman.js は新しく登場した興味深いフレームワークであり、2011年の JSConf でその名前が紹介されましたが、ダウンロードで入手できるようになるまで数ヶ月かかりました。Batman.js は、その MVC アプリケーション開発手法を気に入っているプログラマーの間に普及し始めています。表面的には、取りかかりやすさ、そして宣言型のバインドがビューでサポートされている点で、Batman.js は Knockout.js と似ています。Batman.js が提供する機能には、オプションとしての自動コード生成のためのフルスタックのフレームワーク、ビルド・ツール、さらにはサーバー・サイドの API を実装するためのバックエンドの node.js サーバーまで用意されています。

Knockout.js と同様、Batman.js はビューのバインドを使用します。リスト 3 はビュー・コードの例です。

リスト 3. Batman.js のビュー・コードの例
<ul id="items">
    <li data-foreach-todo="Todo.all" data-mixin="animation">
        <input type="checkbox" data-bind="todo.isDone" data-event-change="todo.save" />
        <label data-bind="todo.body" data-addclass-done="todo.isDone" 
            data-mixin="editable"></label>
        <a data-event-click="todo.destroy">delete</a>
    </li>
    <li><span data-bind="Todo.all.length"></span> 
       <span data-bind="'item' | pluralize Todo.all.length"></span></li>
</ul>

リスト 3 のコードは妥当な HTML5 であり、Batman.js がデータやイベントをバインドするために使用する追加の属性が含まれています。Batman.js では、アプリケーションはモデル、ビュー、コントローラーで構成されます。モデルには妥当性検証機能や、ライフサイクル・イベントを実装する機能、さらには組み込みの ID マップが含まれており、モデルに対して、モデル自体を Batman.LocalStorageBatman.RestStorageBatman.RailsStorage、あるいは独自のカスタム実装を使用して永続化する方法 (アクティブ・レコード・スタイル) を指示することができます。ビューは純粋に HTML で作成されたテンプレートを描画する JavaScript クラスであり、data-* 属性を使用したバインドによってモデル・データをバインドし、イベント・ハンドラーをトリガーします。コントローラーは永続オブジェクトであり、ビューのイベントを処理し、モデル・データにアクセスし、適切なビューを描画します。


JavaScript フレームワークを選択する

大規模で長期にわたるプロジェクトを行おうとする場合には、Backbone.js または Spine.js を検討する価値があります。これらのフレームワークは広く採用されており、遭遇する可能性のある問題に対するサポートを提供しているからです。しかしそうしたプロジェクトの場合でも、成熟したサーバー・サイドの MVC フレームワークを使用した場合に必要となる以上のインフラストラクチャー・コードを作成することになる、ということを理解する必要があります。

ビューに宣言型のバインドを使用するフレームワークの 1 つを実験してみる価値があるかもしれません。そうしたフレームワークには、Backbone.js のようなプロジェクトとは異なる長所と短所があります。宣言型によるビューのバインドを検討している場合には、少し時間をとり、より新しい Batman.js フレームワークに用意された追加機能を試してみてください。Batman.js は他のフレームワークほど一般的ではありませんが、急速に普及しつつあり、単純なクライアント MVC フレームワークを超える広範な追加機能を備えています。

さまざまなフレームワークでプロトタイプを作成し、それらのフレームワークを使用する際の感覚をつかむことが重要です。特にクライアント MVC フレームワークの場合、さまざまな選択肢の中から選択するための方法として、プロトタイピングは最も時間がかからず、最も効果的な方法です。1 つの方法として、チームの各メンバーにいくつかの異なるフレームワークを使用したプロトタイピングを 1 日か 2 日行わせ、その結果を振り返って議論する、という方法があります。最悪のケースとして、それでもいくつかの選択肢が残る場合には、さらにもう 1 日か 2 日を費やし、皆さんがフレームワークを使用する状況で明らかに優れているフレームワークが判明するまで、残されたフレームワークで概念検証を行ってください。

柔軟に計画を立ててください。大量のフレームワークがあって難しいかもしれませんが、どうすればフレームワークへの依存度を最小限にできるかを注意深く考えてください。選択したフレームワークと自分たちのニーズの方向性が異なることが判明した場合には、今後 12 ヶ月から 18 ヶ月の間に別のフレームワークへポーティングするためのバックアップ計画を立ててください。


まとめ

JavaScript によるクライアント MVC フレームワークはまだ成熟していません。この分野は急速に変化しており、誰もが合意するベスト・プラクティスはほとんどありません。大規模なプロジェクトの場合、Backbone.js と Spine.js は共によく使用されており、十分にサポートされている選択肢です。宣言型でビューをバインドする方法を好む場合、Knockout.js と Batman.js の両方をさらに検討する価値があります。

参考文献

学ぶために

  • Backbone.js: データをモデルとして表現する方法を学んでください。
  • Backbone.js on Rails: Backbone.js と Rails を使用してリッチでインタラクティブなアプリケーションを作成するための優れた方法を学んでください。
  • Spine.js: サンプル、スクリーンショット、ドキュメント、その他を入手してください。
  • Knockout: MVVM パターンを適用して動的な JavaScript UI を単純化する方法を学んでください。
  • Batman.js: CoffeeScript または JavaScript を使用してリッチな Web アプリケーションを作成するためのフレームワークに関する情報を入手してください。
  • CoffeeScript: JavaScript にコンパイルされる便利な言語について学んでください。
  • Angular.jsSammy.js: この 2 つも Knockout.js と相性の良いツールです。
  • developerWorks の Web development ゾーン: Web ベースのさまざまなソリューションを解説した記事が豊富に用意されています。Web development 技術文書一覧に用意された、さまざまな技術記事やヒント、チュートリアル、技術標準、IBM Redbooks をご覧ください。
  • developerWorks の Technical events and webcasts: これらのセッションで最新情報を入手してください。
  • developerWorks Live! briefing に参加して、IBM の製品およびツールについての情報や IT 業界の動向についての情報を迅速に把握してください。
  • developerWorks on-demand demos: 初心者のための製品インストール方法やセットアップのデモから、上級開発者のための高度な機能に至るまで、多様な話題が解説されています。
  • developerWorks は Twitter を利用しています: 今すぐ developerWorks のツイートをフォローしてください。

製品や技術を入手するために

  • この記事で紹介した MVC フレームワークをダウンロードしてください。
  • IBM 製品の評価版: IBM 製品の評価版をダウンロードするか、あるいは IBM SOA Sandbox のオンライン試用版で、DB2、Lotus、Rational、Tivoli、WebSphere などが提供するアプリケーション開発ツールやミドルウェア製品を試してみてください。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=824443
ArticleTitle=クライアント MVC フレームワークの調査
publish-date=07122012