QA@IT
この質問・回答は、@ITの旧掲示板からインポートされたものです。

DAOの作成単位について

MVCでWebアプリを作成していると、ほぼ必ずDAOを作成することになると思いますが、DAOの作成単位にいつも悩みます。今までの経験によると大きく二つ「テーブル単位」か「サービス(ビジネスロジック)単位」にDAOを作成している方が多いようですが、それぞれの作成単位によってメリットデメリットがあると思います。この二つ以外にもDAOの作成単位があるかもしれませんが、どちらがよいのか皆さんの意見を聞かせていただきたいです。

1.テーブル単位
【メリット】
 ・同じ処理(SQL)が複数DAOに分散しない
【デメリット】
 ・複数テーブル情報をまとめてSELECTするような場合、どのテーブルDAOに実装するか迷う。
 ・トランザクション処理が必要な一連の処理を記述する場合、テーブル単位では記述できない。

2.サービス(ビジネスロジック)単位
【メリット】
 ・トランザクション処理が必要な一連の処理を記述する場合、違和感が無い。
【デメリット】
 ・複数のサービスDAOで同じ処理(SQL)が書かれる可能性がある。

質問者:どらねこ

回答

私はサービス単位の方がいいように感じます。

サンプルとかを探してみると、テーブル単位の方をよく見かけるので、
テーブル単位で以前は作成していたのですが、複数のテーブルを参照する
時SQLで同様の物が、複数のDAOに作成されてしまったりしたからです。

(これもプロジェクト内の運用で解決出来る問題かと思いますが、、)

投稿者:フライト

編集 履歴 (0)

inaです。
私の考えも、基本的にはサービス単位ですが、
 ・プライマリーキーを指定しての抽出
なんかは、各テーブル単位にもっていて欲しかったりします。

ですので、以下の方法をとっています。
1.テーブル単位のユーティリティ的なDAOを用意※し、基本的にはこれを使用する。
 ※POIやVelocityを使って、テーブル定義書から自動生成させるのがベストです。
2.上記では出来ないもの(≒サービス固有)は各自に実装してもらう。

#「テーブル定義書から自動生成させるツール」を作るのが面倒と言ったら面倒ですが、一度作ってしまうととても便利ですので、おすすめです。
(ついでに、各テーブルのCreate文やレコード格納用Beanも作れますし)

投稿者:ina

編集 履歴 (0)

正規化を行うと、テーブル単位って訳には行かないケースが多いのでは?・・・
テーブル単位でOKなケースって、マスタメンテしか思いつかなくて、
業務ロジックではサービス単位ってことが多いです。

投稿者:かつのり

編集 履歴 (0)

(正規化されているなら)Hibernateを使えば、
テーブル単位のDAOでも結構いけると思うんですけど…
もちろん、サービス単位のDAOがなくなるわけじゃないですが。

投稿者:未記入

編集 履歴 (0)

私はテーブル単位でDAOを作成するようにし、サービス単位のDAOは作成しないようにしています。理由は下記です。
・サービス単位でDAOを作ると類似SQLが複数のDAOに存在するようになり、テーブル定義の変更による修正箇所が多くなりメンテナンス性が低下し、それに従い修正漏れによる品質低下のリスクがある。また、開発工数も余計にかかる。
・DAOのメソッドは1メソッド1SQL、業務ロジックやトランザクション処理は含まないというのを基本ルールすることで、DAOメソッドの共有利用率を高められる。
・トランザクション処理が必要な一連の処理はDAOではなく、DAOの呼び出し元のドメインクラス側に持たせ、トランザクション処理はそのドメインクラスを呼び出すサービスクラスで実行する(実際にはフレームワークに吸収してしまいますが)ことで、トランザクション単位が異なってもDAOメソッドが共有できる。
・SQLは基本的にトランザクションコミット時にバルク発行することでレスポンスを確保することができる(いつもHibernateを愛用しているので不整合も発生しません)。
・Joinや一部の項目のみ取得するような場合は、中心となるテーブルがあるはずなので、そのテーブルのDAOにメソッドを実装するというルールにすることで、どのDAOに実装するか迷うことは無い。

私の場合、ある程度複雑な業務ロジックがあり開発規模も数十人月以上の基幹システムの開発をすることが多いため、上記のような方針とすることでメンテナンス性、品質、生産性を確保するようにしています。小規模なシステムではちょっと重いアーキテクチャかもしれませんが・・・。

投稿者:もっくん

編集 履歴 (0)

皆さん、様々なご意見ありがとうございました。
皆さんのご意見を私なりに統合しますと、テーブル単位のDAO、サービス単位のDAOどちらを使うか?というよりも併用してよい、ということになるかと思います(当然システム内では共通設計にする必要がありますが)。
併用すると、サービス単位DAOからテーブル単位DAOを呼びだす形になり、SQLの共通利用が最も高められると思われます。デメリットとしては数多くのDAOクラスが必要となるため、DAOの自動生成等を行わないと余計に工数がかかる可能性があること。

ここでもう一点、皆さんにご意見を聞かせていただきたいのですが、
トランザクション処理を含むビジネスロジックをどこに書かれているのでしょうか?
DIやAOPは使わない開発の場合です。

1.ドメインクラスに記述
【メリット】
オブジェクト指向としてはドメインクラスにビジネスロジックを持たせることが正しい。
【デメリット】
POJOとして考えた場合、再利用できないデータベースアクセスが入るのは思想に反している。単体テストが簡単にできない。

2.ビジネスロジッククラスに記述
【メリット】
設計やクラス階層がわかりやすく、他のMVCクラスがビジネスロジッククラス以外とは関連が無い状態になる。
【デメリット】
オブジェクト指向的な設計ではない。

また、サービス単位のDAOの認識もそれぞれ若干異なっているかと思います。私の場合はトランザクション処理も含めたビジネスロジッククラスと同じ意味で使っていましたが、皆さんはどのような認識でしょうか?

投稿者:どらねこ

編集 履歴 (0)

私の場合、トランザクション境界はサービスです。
宣言的トランザクション管理が不可能な場合は、
(避けたいですが)サービスでトランザクション制御を行う事になりますね。
ビジネスロジックの実装箇所はドメインモデルです。
OOPエキスパートは、ドメインモデルに実装派が多いようなので、
そのまま受け売りです(恥
というわけで「トランザクション処理も含めたビジネスロジック」は
サービスにあたります。

「サービス単位のDAO」は私にとって集計クエリ用DAO等のイメージです。
テーブル単位のDAOだと明らかにパフォーマンス落ちそうなので、
サービス単位で用意するしか…という感じです。

このあたりの考え方は人によってかなり違うと思います。

投稿者:未記入

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。