Hatena::Groupcatalyst

dann@catalyst このページをアンテナに追加 RSSフィード

2008-03-05

DBを直接モデルとして扱うのは悪か?

00:48 |  DBを直接モデルとして扱うのは悪か? - dann@catalyst を含むブックマーク はてなブックマーク -  DBを直接モデルとして扱うのは悪か? - dann@catalyst  DBを直接モデルとして扱うのは悪か? - dann@catalyst のブックマークコメント

DBICをControllerから直接呼ぶのは本当に悪なのか?、これは一概には言えないんじゃないかと思っているのだけれど、Perl界隈でもそうなんだろうか。以下のようにレイヤ分割して、レイヤ間を疎に保つという話は、Javaの界隈では割によくやられていた話だ。大体以下のような構成だ。

Action -> Service-> Domain Model -> DAO -> OR Mapper

レイヤ間をDIコンテナで繋いで、各レイヤ間の依存関係は最小にして、テスタビリティを高めるというのが定石だった。ドメインモデルがDBに直接依存しないようになっていて、DAOの切り替えができるようになっているわけだ。さらに、Service、Domain Modelは、WebのフレームワークやORマッパなどに依存していない。

ただ、こういう構成は、各レイヤを繋ぐためのレイヤを作るコスト、レイヤを繋ぐデータのオブジェクトを作るコストがある。DBのレイヤが変わると、DTOが各レイヤに波及して、上位レイヤでも作り直しが発生する。Domain ModelのロジックはDBによらずにテストできるようになったが、疎に結合するようにするために数多くのレイヤを用意しなければいけなくなってしまった。

Domain Driven Designが2、3年前に流行った当時は、確かにこういう構成もありなんじゃないかと思っていた。けれど、実際にやってみると、ERモデルとオブジェクトモデルがあわないこともあるし、上記で書いたようにレイヤを用意するコストとレイヤ間を繋ぐコストが高くなってしまうこともある。

上記のような疎にするために余計なレイヤを挟むアーキテクチャよりも、ERモデルを直にモデルにするのでも良いのではないかと思うことが最近は多い。上記のような構成は、レイヤ間の疎結合を実現するために、無駄なコストを払いすぎているんじゃないか思うのだ。

Railsがでてきたときに衝撃的だったことのひとつは、Domain Model, DAO, DBIC部分はひとつにまとめて、ERモデルをそのままモデルとして扱ってしまうというアプローチだった。モデルが簡単に生成できて、DBを直にあらわしたモデルが簡単にテストできる仕組みさがあれば、密にモデルがDBに結合していても機能するんだということに驚いた。

それで結構十分だと思えるケースが結構多いことがあるんじゃないかと思う。だから、それだけRailsが受け入れられたんじゃないかと思う。

ここで言いたいのは、DBのモデルであるERモデルを、そのままモデルとして扱うのは絶対悪とはいいきれないんじゃなかってことだ。ORマッパを置き換えることなんて開発中にはまずないし、ORマッパ依存があったとしても、それは大きな問題じゃない。

モデルはDBに完全に依存していて、かつ各レイヤ間は密に結合していても、そこには無駄なものというのがひとつもなければそのほうがいいんじゃないかって思うのだ。

密結合の問題は、モデルがDBに依存してしまい、モデルのロジックのテストがDBなしでないとやりにくくなってしまうことだけだ。これはテスタビリティが下がり、プロダクト規模が大きくなればうまくいかなくなることがあるんじゃないかと思うこともある。

ただ、ここにはRubyPerlのようなDynamic Languageには解があると思う。テスト実行時にはクラス定義を上書きできるから。これがDIコンテナがRubyPerlでそこまで必要とされないひとつの理由なんだと思う。自分が考える、Perlのフレームワークの理想は、Railsが描くものにきわめて近い。疎にするための無駄なレイヤは作らないというのを基本スタンスをとるということ。

レイヤを疎に保つようににすれば、間に余計なレイヤが存在するようになるし、開発環境のサポートのない環境では、余分なレイヤはテストとコードの二重の変更が重荷になってくる。だから、Javaですら大変だったことは、同じようにPerlRubyでやればさらに大変になることは想像がつく。

だからこそ、簡単にDBICのモデルを直にモデルとして扱うことが悪になるとはいいきれないんじゃないかと思うのだ。

という話をCatalystConで話し合ってみたい!

Railsを触るようになってからドラスティックに考え方が変わったんだけれど、逆にこの密結合モデルは、テスタビリティ上、解決できない問題があるのかっていうのをもっと考えたい。疎に保つアプローチは、時にオーバースペックになりがちってことが、SpringのようなDIコンテナを使っていたときに思ったことの一つで、ピタリとはまるケースもあるんだけれど、そうじゃないケースも結構あるってこと。