Skip to content

Instantly share code, notes, and snippets.

@hakobe
Last active December 20, 2018 04:44
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hakobe/5197847 to your computer and use it in GitHub Desktop.
Save hakobe/5197847 to your computer and use it in GitHub Desktop.
Kyoto.js #7 何がMVCをつなげているのか

何がMVCをつなげているのか

クライアントサイドMVC

  • buzzwordっぽい
  • Backbone.js Angular.js Knockout.js Ember.js とか
  • 使ってますか?
    • はてなでも一部本番運用/社内向けツールではよくみる
  • クライアントサイドMVCフレームワークを利用するとMVCによる設計方針を簡単に使うことができるようになる

MVC!MVC!

  • Ruby on Rails
  • Django
  • Amon2

WebアプリケーションのMVCはここでは忘れろ!!!

MVCパターンって何が良いの?

いつもの図

MVC consists of three kinds of objects. The Model is the application object, the View is its screen presentation, and the Controller defines the way the user interface reacts to user input. Before MVC, user interface designs tended to lump these objects together. MVC decouples them to increase flexibility and reuse.

Gang of Four, DesignPatterns より

  • GUIアプリケーションをModel/View/Controllerに分割する
    • Model : アプリケーションオブジェクト
    • View : スクリーンへの表示
    • Controller : ユーザ入力に応じで何をするかを定義
  • MVC以前はごちゃまぜになっていた
    • これまで書いたJSを思い出し胸に手をあててみよう

MVC間のインタラクションはどうする?

  • Modelが変更されたらViewに反映する
    • Observerパターンで!
  • Viewからユーザ入力が起こったらControllerを起動する
    • Observerパターンで!
  • ControllerからModelのアプリケーションロジックを呼び出す
    • ここは普通に書けばよろしい

Observerパターン

  • Subjectの状態の変更をSubjectに登録されたObserverへ自動的に通知することにより、オブジェクト間の一対多の依存関係を表現するパターン
  • MVCには必須
    • Observerパターンなしでは、フィールドと具体的な処理による強い依存関係が増加

Backbone.js

Backbone.Events

var object = {};

_.extend(object, Backbone.Events);

object.on("alert", function(msg) {
  alert("Triggered " + msg);
});

object.trigger("alert", "an event");
  • 任意のObjectをObserverパターンのSubjectとして利用できるようにする
  • Backbone.js では View と Model のどちらでもBackbone.Eventsextendされていて、MVCの構造を作るのに便利に使える

Backbone.js を利用した例

Backbone.js 以外だとどうなってる?

Ember.js

  • Model View の依存関係を記述し状態の一貫性を保つ方法がたくさん用意されてる
    • バインディング
    • Observer
    • Conputed Property
  • 暗黙的なObserverパターンが多様されてる

Angular.js

  • UIバインディング
  • ControllerがコンテキストになってViewとModelをつなげるObserverになってる

Knockout.js

  • MVVM Angular.jsににてる
  • Observableという仕組みを活用
    • ko.observable(value) のようにすると、値にObverserを登録できるようになる

クライアントMVCフレームワーク

便利な機能がたくさん

  • UI バインディング/ViewとDOMオブジェクトのマッピング/Modelの変更イベントの自動的通知
  • Routing
  • 高機能なController
  • Web API と連携する機能
  • more… (知らないだけでいろいろありそう)

技術的負債になるのではないか?

  • 便利だけど便利な機能に強く依存したコードが完成する
    • UIバインディングはテンプレートにも影響する
  • 将来ライブラリが捨たれた時に技術的負債と化してしまうのでは?
    • Ruby on Rails や jQueryみたいにメンテナンスしばらく続きそうならよいけど..

シンプルに実現する

  • Backbone.jsではModelやViewに便利な機能はあるが、基礎になってるのはBackbone.EventsによるM-V-C間のインタラクション
  • コンパクトな汎用のObserverパターンの実装があればMVCの骨組は構成できるはず(例えば以下のようなライブラリ)
  • いきなり大きなものに依存せず小さいライブラリを活用して自前でMVCを構成する

とはいえ...

  • ViewがHTMLであるのでDOM操作やJSテンプレートエンジンを使う必要がある
    • しかもだいたい毎回似たようなことをするはめに..
  • Observerパターンの実装で設計を良くするだけでは限界がある? UIバインディングは必要?

まとめ

  • クライアントサイドMVCでJSを整理できる
  • Observerパターンの役割
  • クライアントサイドMVCによる保守性の低下はありえる
  • Observerパターンを実現するライブラリのみを使う方法で効率性と保守性のバランスをとれないか
    • とはいえ現実的にはUIバインディングとかも必要になってくる?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment