id:charsbarさんが、先ほど書いたエントリに関して
後半その通りなわけですが、CatalystはModel::DBIC系のせいでMVCが誤解されてるのよねー
と言っておられる。たしかにその通り。「モデルってDBでしょ?」みたいな印象が一般的にあると思う。
そういう印象を持ってる人に説明すると、「モデルを作る」って何かというと、DBのようなストレージにあるものをどうこうする、ではなくて「データに対する操作を抽象化したものを作る」ということです。例えば、ブログを作ると、Blog、BlogEntry、BlogUserみたいなモデルを作ります。そしてその操作方法はこんな感じ:
# ブログを登録するみたいなAPI
MyApp::Model::Blog->create({
user => $blog_user,
title => $title,
....
})
# その後どこかでエントリを作るようなAPI
my $blog = MyApp::Model::Blog->find_by_id ( blog_id => $id );
MyApp::Model::BlogEntry->create({
blog => $blog,
title => $entry_title,
content => $entry_content
});
こんな感じ?見て分かる通り、裏ではDBを使ってるかもしれないけれども、モデルという概念はそれより上の概念。ストレージも含め、ブログエントリを作成する時に行われる全てのステップ(ビジネスロジック)をカバーするのがモデルだ。例えばブログエントリを書く時にHTMLのフィルタリングをするとか、他のサーバーにアクセスしてなんらかのRESTで話すとか、わかんないけど、とにかく「エントリを書く」という行為を抽象化できるところがモデル。
じゃあ元々のブクマコメントのModel::DBICはどうすんだよ、いらないのかよ、みたいなところに行き着くかと思うのだが、そこはそれ、モデルに「格納先」を指定するのにDBを抽象化したModel::DBICを使ってやる、っていう手もある
my $c = shift; # Catalyst的なcontextがあると仮定します
MyApp::Model::BlogEntry->create({
storage => $c->model('DBIC::BlogStorageSchema'),
blog => $blog,
title => $entry_title,
content => $entry_content
});
これで全く問題なくDBICの良いところを使える。
要はDBICはRDBMS特有ストレージのモデル的抽象化であり、本来は他のビジネスオブジェクトの裏で消えているべきところが、実際にはものすごくよく使うものだから同レベルでのモデルが存在する、というそれだけの事。
あなたがこれから書くCatalystアプリはDBICを使うにしてもControllerから直接の呼び出しは避けましょう。それは本来抽象化されているべきことです。そういうふうに組み立てて行くとうまく密結合を防ぐ事ができるはず。
コメント