ひがやすを技術ブログ

電通国際情報サービスのプログラマ

DaoとServiceっている?

今まで
action service dao
って言うレイヤで組んでたので
(いつもserviceとdaoは空っぽに近い)
actionだけで書く、ってのがちょっぴり違和感。

最初にDaoがいるかって話なんですが、あってもいいと思うけど、今後は使われなくなっていくだろうと思っています。
S2JDBCも当初は、Daoの皮をかぶせるつもりだったんですよ。でも、自分で実際に使ってみると、ジョインの仕方が違うだけなのに、メソッドを変えることに違和感がでてくる。または、めんどくさく感じてくる。
S2JDBCの流れるようなインターフェースは適度に抽象化されていて可読性が高いので、Daoのメソッドを呼び出すよりも、何をやっているのかがわかりやすいのです。Daoのメソッド名を適切につければ、Daoのメソッドのシグニチャだけでも伝わると思いますが、引数やジョインのバリエーションが増えてくると適切にメソッド名をつけるのが非常に難しくなります。
Daoパターンの一番のメリットは、データアクセスのコードが1つにまとまっているので、スキーマの変更があったときに、影響範囲を調べるのがやりやすいということがあるでしょう。
たぶん、Daoを使わないときに一番気になるのは、この問題だと思いますが、SQLファイルはテーブルごとにまとめることを推奨しているので、SQLファイルを書く分には問題ありません。
SQLを自動生成する部分は、S2JDBCが自動生成しているんだから、いろんなところから呼び出されていても特に問題はないと考えています。スキーマの変更があった場合も、エンティティを修正すれば良く、個別に呼び出しているコードを修正する必要はほとんどないでしょう。修正する必要があるケースは、Daoを使っていても呼び出し側を修正しなければいけないことがほとんどではないでしょうか。
次にサービスが必要かどうかですが、あってもいいと思うけど、多くのケースではちょっと重い(過剰)かなと思います。
SAStrutsのサンプル(employee)を書くときに、最初は、ActionとServiceは分けていたんです。で、どうだったかって言うと、ActionはS2BeanUtilsを呼び出すコードだけがあり、Serviceには、S2JDBCを呼び出すコードだけしかない。
だったら、1つユースケースに閉じていることは、すべてActionに記述し、複数のユースケースで使われるものをServiceLogicに分割するのがシンプルでわかりやすいのではないかと、そう思ったわけです。
これが、今の私の考えです。
追記:Serviceだとトランザクション境界のServiceと混同しやすいので、Logicがいいんじゃないのという小林さんのアドバイスがありました。確かに、そうですね。Action以外のロジックはLogicに記述するというほうがわかりやすそうです。
追記2:コメントへの回答ですが、ユーティリティは、staticメソッドで構成されるやつは、utilのパッケージ。ActionにDIするやつは、logicパッケージでいいと思います。どっちでもないユーティリティもutilパッケージですね。
Entityについては、SAStrutsのドキュメントにもこのblogでも書いていますが、1つのEntityに閉じたロジックならEntityに記述するということでいいと思います。複数のユースケースで使うからこそ、Entityに書く意味がありますね。個別のユースケースでしか使わないなら、Actionに書いたほうがいいと思います。
LogicにかくのかEntityに書くのかの判断は、1つのEntityに閉じているかで判断するとわかりやすいと思います。複数種類のEntityにまたがっているロジックは、制御ロジックととらえて、Logicに持たせるのが基準が明快なのでわかりやすいのではないでしょうか。