前置きが非常に長い。
週末遊びすぎて、頭の中の奥底に技術系の話がとんでいってしまったので、頭の体操がてらエントリを起こす。以下のエントリを注意深く読んだ。
http://satoshi.blogs.com/life/2009/10/restful-mvcなアーキテクチャの話.html
結論はないです。のでタイトルも適当。
個人的にはどういうアーキテクチャーがよいか、というのは関わる人によって変わると思っているので、
もちろん、これもデザイン・パターンの一つでしかないので、どんな場合にも適用できる話ではないが、少なくとも私が関わっているプロジェクトのほとんどすべてにこのアーキテクチャが適用できそうだな、と思っている今日この頃である。
は、おそらくそうなんだろうと思いつつ、ちょっと気になったのはJSがJSで一言片付けられている点。JSの部分をきちんと顧みないと、
{ "data" : { "html" : "<p>hogehoge</p>" } }
とか、
{ "data" : { "csv" : "a,b,c,d\n1,2,3,4" } }
とか、「ちょっおまwwwなんでJSON?」っていう自体になりかねない点が危惧される。body.innerHTML = data.html; とかやられた日には、さすがにorzになるかと思います*1。 ので、こんな不安を持たざるを得ない環境だと、本来であれば、JS側もどういうモデルを取り扱い、どういうUIトリガー(Controller)を考えて、どういうViewを取り扱うのか、という話になりそう。(ビジネスロジックの結果がそのままUIで使えるモデルであるとは限らないので)、今度はWebのリソースをJS側のモデルにマッピングする?とかそんな話になってややこしくなります。
と、ここまで前置き。。。
だったら、最初っから、UIモデルとそのまま一致するドキュメント指向モデルで行こうよ、というのが最近の私のお好みです。いやまぁ、もともとExcel業務アプリ育ちなのが多分に影響しているのがあるんでしょうけれど。
先日、少しCouchDBでのJOINの表現について書きましたが、私が趣味でいろいろ書いていて得られた結果として*2、CouchDBでJOINしたくなるときは、次のような感じですね。
- 最初にページ(ドキュメント)を設計(画面の中身、ではなくどんな画面が必要か、という話)
- ページ間で必要だと思われるリンクを作るためのデータ項目を追加する
- ページ間をまたがる操作(ポータル的なものとか検索的なものとか)がほしくなると、JOINを唱える。
「最初にページを設計」が重要で、「このページは誰が使うのか」を徹底的に意識します。取引伝票と取引明細は、同じ顧客がINPUTして得られる結果なので、そのドキュメントを表現する画面は一つで済みます。だから、ドキュメントは1つ。一方、ブログエントリとブログコメントは、エントリを書く人とコメントをする人は別の人なので、ドキュメントを分ける方が気に入っています。すると、ブログのPermalink画面を作るときに、あー、JOINしなきゃーって話になったりします。
この感覚、ふと思い出してみると、昔バイト時代に「どの単位でスプレッドシートを分けると使いやすいか」に似ているかも。ああ、JOINはVLOOKUPかw Excelアプリケーションのアーキテクチャー解説書がほしくなってきた。CouchDB/ドキュメント指向のいいところは、画面ベースで設計してもそんなに破綻しないというか、MapReduceでなんとかなるからいいか、とわりきれるところかなぁ。
(追記)
ああ、「リンクを作るためのデータ項目を作る」って辺りが、RDBの正規化の過程と真逆なんだな、と実感した。正規化する場合は、ある大きなデータ項目の集合を分割する際に、関連性を維持すべく参照キーをふるけれど、ドキュメント指向のアプローチだと、「このドキュメントとこのドキュメントは"リンクすべき"」という形であとから追加するんですよね。
なので、ブログエントリとブログコメント、を実装する際、
{ date: "YYYY/MM/DD .." title: "...", body: "...." }
{ name: "...", body: "...." }
というブログ以外にも使えそうなドキュメントを用意しておいて、あとで、コメント側に
{ name: "...", body: "...." blog_id: "..." }
を追加することになるかと思います。ブログ以外にも使えそうな、というのがポイントで、
{ name: "...", body: "...." page_id: "..." }
とすれば、これはWebページに対するコメントに変わります。