PofEAA読書会振り返り

さて、昨日もちょっと触れましたが PofEAA 読書会に行ってきました。Patterns of Enterprise Application Architecture (邦訳: エンタープライズ アプリケーションアーキテクチャパターン) の読書会で、昨日は第10章の Data Source Architectural Patterns でした。Ruby on Rails の O/R マッパであるところの ActiveRecord の元になってるパターン、Active Record パターン (ややこしいな) が含まれる章で、みなさん曰く書籍の中でも特に面白い章だとのことでした。

の 4 つのパターンがありました。

この書籍、こんな感じでいろんなエンタープライズアプリケーションの中から共通してみられるパターンを抽出してカタログ化してみましたというものです。で、DHH がこの書籍を大いに参考にして Rails を作ったとかで非常に大事っぽいことが書いてあるのですが、和訳がちょっと微妙なのと、内容そのものが結構難しいのでなかなか理解するのが難しい! というか僕は正直かなり読むのがしんどいです。そんなわけで一人で読むのは辛いので読書会に参加してきました。

もとい、10章の内容は SQL どこに書くの? 的なパターンでした。

Table Data GatewayJ2EE の DAO に代表されるパターンで、ひとつのインスタンスがテーブルの全部のレコードを扱うというもの。SQL を一箇所に集めることで保守性を上げましょうね、というもの。

Row Data Gateway はそれを一歩進めて、1レコードを1インスタンスで管理するというパターン。ただ、Row Data Gateway ではレコードに相当するインスタンスドメインロジック(ビジネスロジック)を持たない。ドメインロジックをインスタンスが持ってるのが Active Record パターン。

Active Record パターンはクラスの設計とテーブルの構造がほぼ一致、つまり1クラスが1テーブルに対応していて、そのクラスにはドメインロジックも含まれている。(書籍では明示的に触れられてないけど、Row Data Gateway もテーブルとクラスの構造が一致してないといけないってことになるのかな。)

テーブルの構造とクラスの設計に乖離がある場合、その乖離を埋めるためのマッピングを用意してやる必要がある、これが Data Mapper パターン。JavaHibernate とかが Data Mapper による O/R マッピング実装。

という風に理解しました。合ってるかな。

んで、実際に Perl での実装を見た場合、Ruby on RailsActiveRecord にクリソツだといわれる Class::DBI は、やはり Active Record パターンということになりそうです。1クラスが1テーブルに対応していて、その各クラスが同時にドメインモデル(ビジネスロジックが実装されるモデル)でもあります。

ただ、この Class::DBIIma::DBI をベースにしていて、Ima::DBI が何をしているかというと、ひとつはクロージャを使ってコネクションやステートメントハンドラをキャッシュするという仕事ですが、もうひとつは DBI と連携して SQL に名前をつけて管理するということもしています。

Ima::DBI を継承したクラスで、

Foo->set_sql('get_all_foo', 'select * from foo', 'somedb');

としておくと、

my $sth = $foo->sql_get_all_foo;

という感じで、set_sql で登録してある SQLsql_* なメソッドとして呼び出せるという。なので、Ima::DBI を使うときは Ima::DBI を継承したクラスに SQL を書いていくことになるので、Ima::DBI が Table Data Gateway みたいな役割を果たすことになります。

一方で、Ima::DBI はインタフェースが OO っぽくないし使いづらいので、これを OO インタフェースでラッピングしたのが Class::DBI ということになるでしょう。なので、Class::DBI は Active Record パターンな実装ですが、内部では Table Data Gateway も使われているという感じです。

高橋メソッドRuby高橋さんが隣にいたので RailsActiveRecord についていろいろ教えてもらいましたが、Class::DBI と似てるけど実装がだいぶ違うみたいで、面白かったです。

ActiveRecord は DHH が Rails のために実装したものだそうで、その中では RubyDBI も利用しておらず、データベース接続から Active Record パターンによるインタフェースの実装まで、ほぼスクラッチから書かれているらしい。(各 DB 実装へのバインディングは、他の人による実装だそうです。) DBI/Ima::DBI その他 CPAN モジュールをベースに作られている Class::DBI とはその辺りが対照的。

何かと Rails と比較されることが多い Catalyst ですが、miyagawa さんが以前に

Ben のエントリにもあるように RailsCatalyst にはマーケティングのよしあしという決定的な違いがあるにせよ、Catalyst は「CPAN にあるモジュールを徹底的に使いこなして、それをコンテナ的につなげる触媒(Catalyst) 的な動きをする」というのが一番のメリットだなあという風に僕は理解しています。

と「CatalystCPAN モジュールの触媒」と書いてましたが ActiveRecordClass::DBI の作られ方を比較しても似たような印象を受けますね。(Class::DBI が触媒、ということじゃなくて) そもそも CPAN をベースに考えられているという点で。

ところでこの読書会、はてなダイアラーの人がいっぱいいました。特に(高橋さんと反対側の隣に座っていた) id:koichik さんにはいろいろ教えてもらって勉強になりました。アルファギークジュニアな感じの人も何人かいたなあ。あと、この手のコミュニティに共通して見られる傾向ですが、笑いのつぼがとても浅いです。「OO厨」とか厨の付く言葉がでるたびに笑いがおこってました。

3年も前の本で、内容としては最近の流行とはすこし離れてきているそうなのですが、書籍からも読書会からも勉強になることはすごくたくさんあったし面白かったので、次回も参加してみたいと思います。

Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series (Fowler))

Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series (Fowler))