EJB 3.0 に関するこの記事を読んでいます。この記事では、ステートレス セッション Bean として実装された DAO を介してサービス層がエンティティと通信するアーキテクチャについて説明しています。
この追加レイヤーが必要な理由を理解しようとしています。サービス レイヤーがエンティティと直接通信できないのはなぜですか? 私の頭に浮かぶ考えの1つは、テスト容易性です。DAO をモックすることで、サービス層を簡単にテストできます。
これが唯一の理由ですか、それとも他の理由もありますか?
EJB 3.0 に関するこの記事を読んでいます。この記事では、ステートレス セッション Bean として実装された DAO を介してサービス層がエンティティと通信するアーキテクチャについて説明しています。
この追加レイヤーが必要な理由を理解しようとしています。サービス レイヤーがエンティティと直接通信できないのはなぜですか? 私の頭に浮かぶ考えの1つは、テスト容易性です。DAO をモックすることで、サービス層を簡単にテストできます。
これが唯一の理由ですか、それとも他の理由もありますか?
アイデアは、ビジネス ロジック (またはサービス レイヤー) を実際の永続化戦略から分離することです。エンティティは、たとえばフラット ファイルやデータベースに格納できます。ビジネス層に影響を与えることなく、この永続化戦略を変更できるはずです。
サービス層は DAO を介してエンティティと通信します
この文は少しあいまいです。EJB 3.0 では、ビジネス エンティティは POJO です。ビジネス層はそれらを使用でき、データ アクセス層も同様に使用できます。ビジネス層は、ビジネス エンティティと直接「対話」します。ただし、データ アクセス層とも通信します。データ アクセス レイヤーは、主にエンティティの読み込みと保存を担当します。
トランザクション境界は、対処すべきもう 1 つの懸念事項です。EJB 3.0 では、ビジネス レイヤーは、選択された永続性スターテジーとは関係なく、トランザクションの境界を定めます。データ アクセス層とビジネス エンティティは、ビジネス層のトランザクションを実施する必要があります。
DAO をモックすることで、サービス層を簡単にテストできます。
はい。ビジネス レイヤーは、モック データ アクセス レイヤーを使用してテストできます。データ アクセス レイヤーは、ビジネス レイヤーなしでテストできます。繰り返しになりますが、ビジネス エンティティはどちらのレイヤーでも使用できる POJO であるため、これは簡単です。データ アクセス層に必要な情報は、ビジネス層には関係のない注釈を介して提供されますが、ビジネスの観点からビジネス エンティティのモデリングに制約を課すことはありません。
DAOは、オブジェクトを使用してデータベースにアクセスする方法を抽象化したものです。DAO の本来のやり方では、最初に、データベースから期待される操作を定義するインターフェースがあります。
interface ModelDao {
Model load(Long id);
Long save(Model object);
}
これは、一般的なものでも、デザインに合った方法でもかまいません。インターフェイスの高度なテスト容易性とは別に、DAO パターンには、同じ DAO パターンを実装するさまざまなテクノロジを使用できるという別の利点があります。時間が経つにつれて、EJB から Spring JDBC への切り替え、またはその他の変更が必要になる場合があります。
このすべてが発生している間、サービス層は依然としてDAO インターフェースを介してデータ層のみを認識します。実装は常にサービス層からカプセル化されます。さらに、モッキングなどのメカニズムを通じて、サービス層のテスト容易性も向上します。
サービス層が直接データ層を処理し始める場合、それはサービス層が実装固有になることを意味します。これは、ビジネスロジックのためだけにサービス層をテストすることを難しくすることとは別に、モジュール性と懸念の結合を減らします。
最後に大事なことを言い忘れましたが、元の慣行に固執することが常に最善ですが、アプローチを採用するかどうかは、製品/プロジェクトの規模と意図によって異なります。
私の頭に浮かぶ考えの1つは、テスト容易性です
いいえ、DAO レイヤーを簡単にテストできるようにするためだけに存在するわけではありません。この場合のDAOの目的は、懸念を分離することです。
@ewernli と @nobeh は、DAO レイヤーの目的などを説明しています。追加したいのは、問題を解決するためのアプローチの 1 つです。むしろ、Java の世界では、DAO の明示的なレイヤーを使用するこのアプローチはかなり前から存在していました。実装できる代替アプローチがあります。たとえば、Ruby/RoR の世界のActiveRecordの場合を考えてみましょう。
サービス層がエンティティと直接通信できないのはなぜですか?
はい、サービス層がエンティティと直接対話するようにアプリケーションを設計できます。DAO の使用に反対し、ドメイン駆動設計の使用を提案する特定の人々がいます。
永続性のために別のレイヤーを用意するという全体的なアイデアについての私の個人的な意見は、ちょっと面倒です。あなたが指摘したアプローチでは、エンティティは単に情報を格納するためのデータ構造またはブロブ(ゲッターとセッター)として機能しています。ほとんどの場合、ビジネス ロジックは追加しません。