web-dev-qa-db-ja.com

サービス層を使用する理由

私は http://solitarygeek.com/Java/developing-a-simple-Java-application-with-spring/comment-page-1#comment-1639 の例を見ました

彼が提供する例の最初の場所でサービス層が必要な理由を理解しようとしています。あなたがそれを取り除いたなら、あなたのクライアントでは、あなたはただ行うことができます:

UserDao userDao = new UserDaoImpl();
Iterator users = userDao.getUsers();
while (…) {
…
}

サービス層は、DAOの単なるラッパーのようです。サービスレイヤーが削除された場合、事態が乱雑になる可能性があるケースを誰かが教えてもらえますか?サービスレイヤーを最初から用意する意味がわかりません。

31
joe martinez

サービス層をDAOのラッパーにすることは、一般的なアンチパターンです。あなたが与える例では、それは確かにあまり役に立ちません。サービスレイヤーを使用すると、いくつかのメリットがあります。

  • コントローラーで最適に実行されるWebタイプのアクティビティと、Web関連ではない一般的なビジネスロジックを明確に区別できます。コントローラ関連のロジックとは別に、サービス関連のビジネスロジックをテストできます。

  • トランザクションの動作を指定できるので、複数のデータアクセスオブジェクトへの呼び出しがある場合、同じトランザクション内で発生するように指定できます。あなたの例では、daoへの最初の呼び出しがあり、その後にループが続きます。おそらく、より多くのdao呼び出しが含まれる可能性があります。これらの呼び出しを1つのトランザクション内に保持することは、データベースの処理が少なくなることを意味します(Daoへの呼び出しごとに新しいトランザクションを作成する必要はありません)。

  • サービスをネストして、トランザクションの動作が異なる場合(独自のトランザクションが必要な場合)に強制することができます。

  • postCommitインターセプターを使用して、電子メールの送信などの通知を行うことができるので、コントローラーに迷惑をかけることはありません。

通常、私は単一のタイプのユーザーのユースケースを網羅するサービスを持っています。サービスの各メソッドは、そのユーザーが実行する単一のアクション(単一の要求/応答サイクルで実行される作業)であり、あなたの例とは異なり通常、そこで行われるのは、単純なデータアクセスオブジェクトの呼び出しだけではありません。

31
Nathan Hughes

次の記事をご覧ください。

http://www.martinfowler.com/bliki/AnemicDomainModel.html

それはすべて、ロジックを配置したい場所(サービスまたはドメインオブジェクト)に依存します。

複雑なアーキテクチャがあり、DAOとデータへの異なるインターフェイスが必要な場合は、サービスレイヤーアプローチが適切です。データを取得するためにクライアントが呼び出す複数のDAOを呼び出すための、きめの細かいメソッドを提供することもよいでしょう。

ただし、ほとんどの場合、必要なのは単純なアーキテクチャなので、サービスレイヤーをスキップして、ドメインモデルのアプローチを検討します。 Eric Evansによるドメイン駆動設計とInfoQの記事は、これをさらに詳しく説明しています。

http://www.infoq.com/articles/ddd-in-practice

19
Jon

サービスレイヤーの使用は、Javaコミュニティーで広く受け入れられている設計パターンです。はい、すぐにdao実装を使用できますが、ビジネスルールを適用する場合はどうでしょうか。

たとえば、ユーザーにシステムへのログインを許可する前に、いくつかのチェックを実行するとします。あなたはそれらのロジックをどこに置きますか?また、サービス層はトランザクション境界の場所です。

一般に、DAOレイヤーをクリーンで無駄のない状態に保つことをお勧めします。記事を読むことをお勧めします 「DAOを繰り返さないでください」 。その記事の原則に従うと、DAOの実装を作成できなくなります。

また、そのブログ投稿の範囲はSpringの初心者を支援することでした。 Springは非常に強力なので、aopなどの強力な概念を使用してニーズに合わせて曲げることができます。

よろしく、ジェームズ

19