Hatena::Groupcatalyst

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

2008-03-06

Catalyst と MVC

01:51 |  Catalyst と MVC - dann@catalyst を含むブックマーク はてなブックマーク -  Catalyst と MVC - dann@catalyst  Catalyst と MVC - dann@catalyst のブックマークコメント

charsbarさんのお陰で、miyagawaさんがいっていることは、自分で納得できるところまでは理解できた気がしたので、まとめておきたい気もするんだけれど、今日はもう疲れたのでここまで。

Catalystのグループ用のメモとして、id:miyagawaさんのエントリにだけリンクははっておこう。結局、殆どmiyagawaさんのエントリに解が書いてあったということなので。

http://subtech.g.hatena.ne.jp/miyagawa/20080306/1204761778

テーブル:モデルが1:1になることの問題点はなんだろう?

01:51 |  テーブル:モデルが1:1になることの問題点はなんだろう? - dann@catalyst を含むブックマーク はてなブックマーク -  テーブル:モデルが1:1になることの問題点はなんだろう? - dann@catalyst  テーブル:モデルが1:1になることの問題点はなんだろう? - dann@catalyst のブックマークコメント

id:Baysideさんの話

http://d.hatena.ne.jp/Bayside/20080306/p1

以下の点は理解できます。

  • 複数のロジックを束ねるのにL(miyagawaさんがいっているCに近いもの)を置く
  • Controllerにロジックを書くのはよくない

ただ、以下の点はよくわからないです。

  • Catalyst 用語でいう stash と session は MyApp::Logic 内で隠蔽化してしまうと幸せになれます。
  • テーブル:モデル=1:1 じゃダメ

sessionがLogic内で隠蔽されたら、LogicがWebのコンテキストに依存してしまうので、直感的には良くない気がします。また、テーブル:モデルが1対1だとダメな理由というのがよくわからないです。

DBにしか入れないデータでも、DBICのモデルにロジックを置くのは悪なのか? - その2

01:15 |  DBにしか入れないデータでも、DBICのモデルにロジックを置くのは悪なのか? - その2 - dann@catalyst を含むブックマーク はてなブックマーク -  DBにしか入れないデータでも、DBICのモデルにロジックを置くのは悪なのか? - その2 - dann@catalyst  DBにしか入れないデータでも、DBICのモデルにロジックを置くのは悪なのか? - その2 - dann@catalyst のブックマークコメント

DBにしか入れないデータでも、DBICのモデルにロジックを置くのは悪なのか?」の記事のcharsbarさんのコメントを読んでみて、そんなに自分が考えていた仮定もそんなに間違いではないかもしれないなと思いました。

以下、id:charsbarさんのコメントです。

モデルそのものに押し込むのは正しいけど、Catalystのモデルに押し込んでしまうとCLIなどで使い回すときに不便だから避けた方が無難ということになってきている、ということかと

DBICのモデルにロジックを書くのは間違いではないけれど、「Catalystのモデル」にロジックを書いてしまうと、「Catalystのモデル」はフレームワークに依存してしまうから、CLIなどなどで使いまわすときに不便なので避けたほうがよい

という話なんだと理解しました。これで大分すっきりしました。DBICのモデルという書き方だと少し誤解を招くかもしれませんが、多分理解は間違ってないんじゃないかなぁと。id:miyagawaさんが書かれている話も、Modelを「Catalystのモデル」と置き換えてよむと、すんなり読めます。

Model に直接メソッドを書いて Controller から呼び出すのも別に悪くはないとおもうけどイベント処理とかいろんなところからメソッド呼んだりするので共通化できるメリットがあるし、 Web コンテキスト関係なくテストできるのでユニットテストも書きやすくなる。

これで、細かい点でどう実装するのか検討する点はありますが、大体どう作っていったほうがよいのかというのは分かった気がします。たった1日で疑問に思っていたことの大部分が解決してしまった!Blogって素晴らしいなぁ。

こういうときには機能しないよっていう話があったら、それも是非聞いてみたいですね。そういう話はとても貴重だと思うので、色んな人の話を聞いてみたいなと。

# これって、Virtual CatalystCon!

# そもそも、解釈がぜんぜんちげーってことだったら、是非教えてください。

フレームワークとの密結合していてよいのは?

22:42 |  フレームワークとの密結合していてよいのは? - dann@catalyst を含むブックマーク はてなブックマーク -  フレームワークとの密結合していてよいのは? - dann@catalyst  フレームワークとの密結合していてよいのは? - dann@catalyst のブックマークコメント

モデルがフレームワークに完全依存していたとしたら、それが問題なんじゃないかなぁというのは思っています。個人的には、ViewとControllerについては、フレームワークに依存していてもよいと思っています。

Controllerについては、Controllerがフレームワークに密結合していてもよいと思っています。というよりも、Controllerがフレームワークに密結合していないWebのフレームワークって一体なにをするんだ?っていう気すらします。Controllerには直接ビジネスロジックは書いてはいけないとは思っています。

CatalystのViewでCatalystのContextオブジェクトに依存する形で(例えばuri_forとか)、僕はコードを書いてますが、それは別に気になりません。Viewのファイルだけを単体でテストすることがないからです。

ただ、ビジネスロジックがフレームワークに依存するというのは、テスタビリティ上の問題があると思っていて、これは言語によらず問題なのではないかと思っています。

ただ、DBICのモデルにロジック書くのは、フレームワークには依存してないと思うんですよね。

DBにしか入れないデータでも抽象化は必要か?

22:22 |  DBにしか入れないデータでも抽象化は必要か?  - dann@catalyst を含むブックマーク はてなブックマーク -  DBにしか入れないデータでも抽象化は必要か?  - dann@catalyst  DBにしか入れないデータでも抽象化は必要か?  - dann@catalyst のブックマークコメント

id:yappoさんの日記に空前のMVCブームにのった記事のリンクが張られています。

http://d.hatena.ne.jp/yappo/20080306/1204781864

一通り全部のBlogを読んでみても、やっぱりまだしっくりとこないところが結構あるなぁということで、もう少し深く議論をしたい!

読んだ記事の中でも、id:miyagawaさんの記事は、納得できる話が多かったです。

納得しているのは、

  • LDAPDBなど異なるストレージに対する操作を抽象化するときに、抽象化したモデルが必要であるということ
  • 複数の M を操作するプロシージャコールみたいなメソッドをまとめて定義したクラスを用意する

という点です。

一つ目の話は、dmakiさんも書いていることです。これは自分もそう思います。これは、これしか解がないように思います。dmakiさんのBlogの例やmiyagawaさんのLDAPの例については、ストレージレベルでの抽象化が必要なデータだから、抽象化したデータモデルが必要なんだと思います。ここまでの話は特に違和感も何もなくて、自然な話だと思う。特に疑問に思うところがないです。

2つ目の話は、複数のモデル(DB)を操作するクラスが必要という点については、自分もそうなんじゃないかなぁと思ってます。ただ、一つのMだけに必要なロジックも、C というクラスに置いたほうがよいのか?というのは、わからないです。これについての疑問は、次のエントリに書きます。

まずは、話が長くなるので、一つ目の話だけをします。

  • DBにしか入れないデータがあったとしても、常に抽象化する必要があるのか?

1番目については、最近はNoだと思っています。将来的に抽象化が必要なことが予想されるのであれば、抽象化が必要なものなんだと思ってます。

DBにしか入れないデータでも、DBICのモデルにロジックを置くのは悪なのか?

22:26 |  DBにしか入れないデータでも、DBICのモデルにロジックを置くのは悪なのか? - dann@catalyst を含むブックマーク はてなブックマーク -  DBにしか入れないデータでも、DBICのモデルにロジックを置くのは悪なのか? - dann@catalyst  DBにしか入れないデータでも、DBICのモデルにロジックを置くのは悪なのか? - dann@catalyst のブックマークコメント

yappoさんのBlogからのリンクの記事を読んでみても、自分が疑問に思っていることは、やっぱり解決していないなぁと思っています。

自分が疑問に思っているのは、

DBにしか入れないデータで、複数のモデルにまたがらないロジックでも、DBICSchemaにロジックを置くのは悪なのか?」

ということでです。

僕は、データを知っている人だけが、そのデータに対する振る舞いを定義するべきなんじゃないかと思うわけです。

その点、複数のモデル(データ)にまたがるロジックは、一つのDBICのモデルに押し込むのは変で、Serviceクラス(宮川さんが書いているCクラスに書くのは自然なことなんだと思っています。

こうしたときに、DBICのモデル(テーブルに対応)に固有のロジックは、DBICのモデルに直に書くのがいいんじゃないかと思っていて、何でそこに書いていけないのか?と思うのです。これに対する解は、どの記事にも書いていないように思いました。(自分の理解が正しければ、RailsのAcriveRecordは、まさにDBICのモデルに直にロジックを書く形なんじゃないかと思っています)

これに対する予想される解は、以下のことが考えられます。

  • DBICという一つのORマッパに依存してしまうこと
  • モデルがDBに依存することで、テスタビリティが下がること

一つ目の解である、「ORマッパへの依存」については、自分は問題ないと思っているというのは前の記事で書きました。開発後にORマッパを以降することがないからです。また、ORマッパの差異を吸収するラッパを書いて、それを使うというのは、現実的ではないと思っているからです。

二つ目の解である、テスタビリティが下がることについては、解があるんじゃないかという記事を書きました。Rails界隈のBlogをざっとみた限りでは、以下の記事は自分が思っている解に近いものだと思いました。簡単にまとめると、ActiveRecordの一部メソッドをStubでつくり、カラムのデータをテスト用に作るというものです。

http://blog.jayfields.com/2006/12/rails-activerecord-unit-testing.html

要するにORマッパレベルでStubを作ることで、DBへの依存を断ち切るわけです。多分、DBICでも同じことができるんじゃないかと思っています。簡単にStubが作れれば、テスタビリティが下がるという問題もなくなってしまいます。

DBなしでもUnitTestができるわけで、これも問題になりません。UnitTestレベルでは、DBに依存しないテストが簡単に作れそうです。

そう考えると、やっぱりどうしても、DBICのモデルにロジックを記述することの問題点というのがわからないのです。何が問題になるのだろう。これは、ActiveRecordのモデルにロジックを書くのは、何が問題なのかっていうことの問題と同じなんじゃないかと殆ど同じだと思っています。

このDBICのモデルにロジックを置く事に、何か問題(開発効率上、テスタビリティなどなど)があるのであれば本当に教えてもらいたいなぁって思う。

これで問題があれば、結局のところJava界隈で話されていたアーキテクチャに戻るということも当然あるとは思っているんですが、今のところこれといった問題がないように思えてしまうんですよね。Javaでは、DAOを切り離すしか解がなかったと思うので、アーキテクチャとして、ORマッパのモデルにビジネスロジックを置くという解がそもそもなかったと思います。だから、前のエントリで書いた、レイヤを切り離すアーキテクチャは正しかったんじゃないかと思います。ただ、Dynamic Languageでのアーキテクチャには、別の解があるんじゃないかと思っていて、それこそが自分の疑問点の始まりだったりします。

# DBICのモデルにロジックを置くのは間違いなのか?というのは、ActiveRecordのモデルにロジックを置くのは間違いなのか?と読み替えてもらってもよいのではないかと思います。

トラックバック - http://catalyst.g.hatena.ne.jp/dann/20080306