2008-09-11

Observerパターン

前から興味のあったデザインパターンの本を購入。(→ Head Firstデザインパターン)。Javaは知識レベルでしか知らないので難しいかと思ったが、以外にいけた。まだ2章までしか読んでないけどおもしれえ。で、その2章のお題目であるObserverパターンがさらにおもしれえ。簡単に言うと、「何か変化がおきたときに、複数のオブジェクトに通知する」っての(詳しくはWikiへ)。

例えば、「定期的にサーバにデータを取得しにいって、更新があった場合に複数のオブジェクトに一括で更新を通知するオブジェクト」なんてのは、Ajaxを使ったWebアプリケーションだったらよくある。こういうのにまさしく使えるパターン。これを実装するとしたら、

/*-------------------------------------------------------*/
/* 更新を通知してくれるクラス
/* デザインパターンだと、サブジェクトと呼ぶ。
/*-------------------------------------------------------*/
var Subject = function() {
  this.list = [];
};
Subject.prototype = {
  // 通知対象を登録するメソッド
  register: function(observer) {
    // 通知を受けるメソッドはupdateメソッドを実装している必要がある。
    // Javaだと、updateの実装を強要できる、インターフェースという機能があるけど、
    // JavaScriptはないので、ここでupdateが実装されているかチェックする。
    if (!observer.update)
      throw new Error("this object doesn't have update method.");

    // リストに登録
    var list = this.list;
    for (var i=0,len=list.length; i<len; i++)
      if (list[i] === observer)
        return;
    list.push(observer);
  },

  // 通知対象を削除するメソッド
  remove: function(observer) {
    var list = this.list;
    for (var i=0,len=list.length; i<len; i++)
      if (list[i] === observer)
        list.splice(i, 1); return;
  },

  // 通知メソッド
  //(通知される側はupdateというメソッドを実装する必要がある)
  notify: function(data) {
    var list = this.list;
    for (var i=0,len=list.length; i<len; i++)
      list[i].update(data);
  }
}

更新を受け取る側は、

/*-------------------------------------------------------*/
/* 更新を受け取るクラス
/* デザインパターンだと、オブザーバーと呼ぶ。
/*-------------------------------------------------------*/
var Observer = function(){};
Observer.prototype = {
  // 更新通知をお願いするメソッド
  subscribe: function(subject) {
    subject.register(this);
  },
  // 更新通知をやめてもらうメソッド
  unsubscribe: function(subject) {
    subject.remove(this);
  }
}

使い方は、

var sub = new Subject();
sub.change = function() {
  var data = "hogehoge";
  if (/* dataが更新されていたら */) {
    this.notify(data);
  }
}

var obs = new Observer();
obj.update = function(data) {
  // 実装
}
obs.subscribe(sub);

みたいになる。そうすると、sub.change()で更新を検知すると、登録されているオブザーバーにupdateメソッドを通して更新を通知する。

実際にこのコードを使ったサンプルはココ(サーバーから定期的に時間を取得し、複数の方法で表示するようなの)。

Posted at 02:18 in | WriteBacks (0) | Edit

2008-09-09

AskMyself

人気ブログのIDEA*IDEAさんで紹介されていた「週に一度、日曜日に自問すべき20の質問」という記事を見て、週末でWebサービスを作れるかを神が試しているに違いないと思い込み、ちょっと立ち上がってみた。

作ろうと思ったのは、自問自答を支援するWebアプリ。なんか簡単そうだなと思ったんですが、俺には週末だけで作るスキルはありませんでした>神。一応、月曜に最低限の機能を実装したものができたけど、まあ作りはひどい。多分バグとかもくそあるはず。あと、クソ地味。一個も画像がないってのは、ある意味すげえと思う。まあ、少しずつ良くしていくしかねえな。

これぐらい懺悔的なことを書いておけば公開してもいいですかね?

AskMyself

使い方ですが、デモ用のアカウント(guest/guest)を用意してますので、それで使っていただければわかると思います。あと、フィードバックがあれば、コメントかメール(thethirdshurenあっとgmail.com)でお願いします。内容によりますが、できるだけ対応したいと思っています。

実際のところ、自問自答の履歴を管理できればそれでいいやみたいに思っているので、これ+R*PADで僕は現状満足してたりします。

あー、にしても日曜中に作り上げたかったなー。素早い開発したいわりにフレームワーク使えないのがダメな気がしてきた。Railsでも勉強するか。>俺

Posted at 00:55 in | WriteBacks (0) | Edit

2008-08-13

IT的な実務能力を測る問題 #2

IT的な実務能力を測る問題 #2
あるディレクトリにHOGE_1からHOGE_1000までの1000個のファイルがある。このファイルをHOGE_XXXのXXXの数値順にソートしたリストを作成しなさい。(5分)

ちょっと面倒そうだったので、XXXの上限が1000と割り切った方法。30秒くらい?

ls HOGE_? | sort; ls HOGE_?? | sort; ls HOGE_??? | sort; ls HOGE_???? | sort

XXXの上限がとんでもなければ、それはそのとき考えるかなあ。

Posted at 21:10 in | WriteBacks (0) | Edit

2008-07-29

JavaScriptのテンプレートエンジン

いろんな人がそれぞれのやり方でやっているわけですが、個人的にはテンプレートをHTMLとして書ければいいや、くらいなのでちょっとしたのを書いてみた。

まずはHTMLがこんなん。特別な記法はないけど、テンプレートとして使用するHTMLにIDを振っておく必要がある。

<div id="container">
  <div class="head" id="t_head">
    <h3 id="t_title"></h3>
    <h4 id="t_direction"></h4>
  </div>
  <div class="etc"></div>
</div>

これに、

// テンプレートとして使いたい要素のIDを渡すと、
// スタイルも含めてテンプレートに準じたエレメントを作る。
var dom = new Template('container');

// 該当IDのinnerHTMLを埋めてくれる
dom.fill({
  t_title: "タイトル",
  t_status: "説明文"
}

// innerHTMLを使っているので、
// こうするとid:t_title、id:t_statusが消えるから大変。
dom.fill({ t_head: "あたま" });

// IDが振られているものはこうやってアクセスできる。
dom.container
dom.t_direction

非インテリジェントだけどわかりやすいし、コードみやすくなるし、自分の場合は大抵これで問題ない。

いや、問題あった。場合によってはテンプレートのHTMLが見えないようにdisplay:noneとかを設定する必要があることと、個別のidに対して設定しているスタイルは引き継がれないこと。(引き継ぎたいスタイルはclassに対して設定してあげる。)

スピードは気にならないので実装は特に工夫していない。(気になればその時考える。)

ソース

Posted at 08:08 in | WriteBacks (4) | Edit

2008-07-21

時系列マップを作った後でTimelineの存在に気付いて凄く後悔しています。

そういうわけで、時系列なマップを使って何かをしたい人はTimelineを使えばいいと思います。

当初は、使いまわしの利きそうなマップの開発を考えてたけど、Timelineの存在に気付いてからは、役に立たなくても何かしら機能をつけて公開だけはしてやろうってことで、意地でRSSフィードをマッピングする機能をつけました。→問題のページ

できることはといえば、

  • ドラッグでのマップの移動
  • 十字キーでの移動
  • 1ページあたりに表示する期間の指定
  • RSSフィードのインポート(dc:dateてきなのを含むもの)
  • フィルタリング

くらい。適当なフィードをぶっこんでもらえばわかると思います。もうあんまり見たくないのでTimelineとの違いはわかりません。タイトルには「作った後」とか書いたけど、正直使いまわしは利かない(!?)。分かってるバグもいくつかあるけど、IE6、Opera9.51、Firefox2.0.0.16ではある程度動くことが確認できたので公開しときたいと思います。

いろんな意味でけっこうくやしいので、これを利用して使えるサービスが出来ないか色々やってみようと思う。

ToDo
  • リファクタリング
  • 使いまわしが利くようにする
  • これを利用して何かつくる
  • Timelineのコードを読む

問題のページへ

Posted at 15:27 in | WriteBacks (0) | Edit