Backbone.jsでJavaScriptプログラムが疎結合に書けるのは、オブジェクト(Model)とビュー(View)が明確に分離されていて、オブジェクトの変更が随時ビューに伝搬する仕組みになっているためです。
jQueryに限界を感じた人にぴったりのJavaScript MVCフレームワークBackbone.js
オブジェクトが変更された時に、その変更をビューに通知し、それを受けてビューを更新するという設計を、オブザーバーパターンと呼びます。
17.Observer パターン | TECHSCORE(テックスコア)
一瞬脱線しますが、デザインパターンについてはこの本がとても分かりやすいのでおすすめです。
増補改訂版Java言語で学ぶデザインパターン入門
オブザーバーパターンを使わないタイマー
Backbone.Eventsを使うと、簡単にオブザーバーパターンが書けます。
オブザーバーパターンはビューとオブジェクトを疎結合にするのが目的です。ここでは逆に、オブザーバーパターンを使わないと独立性の低いプログラムになってしまうという例を示してみます。
テキトーにタイマーで数字をカウントアップしていくプログラムを書いてみました。
var i = 0;
setInterval(function() {
i++;
$('#counter').text(i);
}, 100);
これは確かに動きます。
しかしながら、タイマーの表示対象のビューを増やそうと思うと、タイマー自体がどんどん肥大化していきます。
たとえば、ただの数字だけでなく、プログレスバー表示をしてみます。
タイマーの中に、カウンターとプログレスバーの処理を混ざっていて、複雑な表示をしようとすればするほど、タイマー自体が複雑になってしまいます。
var i = 0;
setInterval(function() {
i++;
$('#counter').text(i);
var str = '';
for (var j = 0; j < i; j++)
str += '|';
$('#progressbar').text(str);
}, 100);
このくらいのプログラムだったら問題ないですが、ブラウザベースのAjaxアプリケーションなどでは、この数十や数百のオブジェクト、ビューを管理する場合もあります。このままではまともに動かなくなるのも時間の問題でしょう。
ビューをオブザーバーとして切り出す
そこで登場するのがオブザーバーパターンです。
オブザーバーパターンでは、オブジェクト自体がそのビューについての情報を一切持ちません。
たとえば、次のようにタイマーを書きます。これは純粋にタイマーであって、表示に関する処理を一切書いてないのがポイントです。その代わりにタイマーの値が変わったことをイベントnofityとして発生させています。
var timer = _.extend({
start : function() {
var i = 0;
setInterval(function() {
i++;
timer.trigger('notify', i);
}, 100);
}
}, Backbone.Events);
timer.start();
ビューは次のように、タイマーと分離された形で書くことができます。counterオブジェクトは、timerのnotifyイベントを観測し続けていて、timerがイベントを発生させたタイミングでビューを更新します。
var counter = _.extend({}, Backbone.Events);
counter.listenTo(timer, 'notify', function(i) {
$('#counter').text(i);
});
次のプログラムは、プログレスバーのビューです。数字のビューと、プログレスバーのビューも完全に分かれているので、片方だけを使うなどという状況にも簡単に対応できます。
var progressbar = _.extend({}, Backbone.Events);
progressbar.listenTo(timer, 'notify', function(i) {
var str = '';
for (var j = 0; j < i; j++)
str += '|';
$('#progressbar').text(str);
});
このようにオブザーバーパターンを使うと、ビューとオブジェクトを明確に分離することができ、それぞれが複雑化しても安全に実装できます。
そんなオブザーバーパターンは、Backboneでは、Eventsオブジェクトを使うことで簡単に作ることができます。上の例で実際に書いた通りです。
これはBackbone.Eventsだけを使った例ですが、BackboneのModelクラス、ViewクラスなどはすべてEventsの機能を持っていて、更に拡張されています。だから、Backboneでは、ビューが明確に分離されて、複雑なWEBアプリケーションでも整然と実装していくことができます。
コメント