Catalystでロジックをどこに置くかという話

Catalystをちゃんと勉強しはじめてからずっと頭の片隅にあるけどまだ解決せず。
俺以外にも悩む人はぜったいいるはずだと思っていたけどMLを検索する方法がよくわかんなかったのでいまいち網羅できず。ひとまず、
Catalyst MVCの覚え書き - libnitsuji.so
こんな感じだったのだが、今日、
http://www.mail-archive.com/catalyst@lists.rawmode.org/
を見つけたので「logic」で検索!
興味深いスレッドとして、
[Catalyst] Program the logic
[Catalyst] ways to do stuff and why
の二つがあったので読んでみた。
実装までは踏み込んでいないのでそれ以前の話だけど。俺の頭の中もまだ実装前なので具体的にどう実装するかはひとまず置いておく。
俺の疑問点とか考えとかを書いてみる。

  1. ロジックはWebのコンテキスト固有のものではなくアプリケーションに固有のものなので、Webのコンテキストに属するControllerに置くべきではないんじゃないか。なぜなら、そこに存在するロジックは他のコントローラからは基本的に使えないし、また、cron起動するコマンドラインスクリプトからも使えない。
  2. じゃあロジックをどこに置くかというと、モデルに置くか全く別のモジュールに置くかということになるがどっちがいいのか。

MLから引用するとここ。

At this point, if I want code reuse I have two reasonable choices:

A) Create business logic modules, ie. MyApp::Logic::CreateTrial, etc
B) Write my own business logic methods in MyApp::Schema::Trial->create(...)
Re: [Catalyst] ways to do stuff and why

モデルに置く

1つ目。DBICでResultSetManagerを使ってモデルを拡張?してロジックを置く。こうするとControllerからロジックを追い出せるけどロジックがモデルと密結合になってしまうのがいまいちな気がする。モデルを変えたらロジックに大打撃。2つ目。CatalystのModelとしてロジック用モジュールを書いてそこからDBICを使う。モデルからモデルを呼ぶ形?MLから引用するとここ。

Actually, I tend to have a DBIC::Schema model called something like
'DataStore' and then write logic modules under Model::* that the controllers
call - so "mostly (a), with a bit of (b)"
Re: [Catalyst] ways to do stuff and why

なんかこれでいい気がする。で、純粋な疑問としてこのunder Model::のメソッドをコントローラから呼んだときに何が戻ってくるかというと、単純にやるとDBICの場合ResultSetとかRowオブジェクトになりそうで、その場合、ControllerとかViewがそれに縛られちゃうんじゃないかと思うんだけど、またMLから引用。

I tend to return the DBIC objects but make sure the controller only ever
interacts with *semantic* methods rather than the DBIC-specific
find/search/etc. so I could swap it out for such an extra layer if I ever need
to.
Re: [Catalyst] ways to do stuff and why

semantic methodsってよくわかんないけど、とりあえずDBIC固有のメソッドは使わないようにすれば簡単に置き換え可能(インターフェースをあわせることで)ということですかね。緩い解決法なので意識の共有がうまくできてないと複数人で開発した場合に絶対に破綻する。

別のモジュールに置く(たとえばMyApp::Logic:: )

コントローラとモデルの間にこれを置くことで層をわけちゃう。MVC + Lな作り。Javaっぽい。
MLではこれが支持されていた印象を受ける。モデル(データアクセス層)とロジックを切り離すってのが目的かな。Handelの手法がとても参考になる。MLを引用するとさっきのa) or b)ってやつの返信からいくつかで「賛成ー」「おれもー」みたいなのがあります。
http://www.mail-archive.com/catalyst@lists.rawmode.org/msg01144.html
欠点としてはモジュールが増えるので手間が増える。エンティティオブジェクトみたいなのが別途必要?(DBICのRestulSetとかRowを使えない(使ったらこの層の意味激減)ので)とりあえずHandelをもっと見てみるといいかも。

で、これを言っちゃうと元も子もないんだけどどっちでもいい気がする。ちゃんと関心の分離(Separation of Concern)ができていて、何をどこに置くか基準があり、みんなで意識の共有ができてることが重要。

そういえばControllerでModelからResultSetをもってきてあとはViewでガリガリやるって方法もありますね。
あまり採用したくないけど。