web-dev-qa-db-ja.com

Java EEアーキテクチャ-JPA 2のようなORMを使用する場合、DAOはまだ推奨されますか?

JPA2のようなORMを使用している場合-データベースにマップされているエンティティがある場合でも、DAOを使用する必要がありますか?オーバーヘッドがはるかに多いようです。

たとえば、3つの追加パッケージを維持する必要があります。

  1. ドメインオブジェクトを指定するもの(エンティティオブジェクトをほぼマップします):

    public class Employee {
        private String firstName;
        private String lastName;
        ...
        // Getters and setters
    }
    
  2. DAOメソッドを指定するインターフェイスを含むもの

    public interface EmployeeDAO {
        public void addEmployee(Employee employee);
        public Employee getEmployeeById(long id);
        ...
    }
    
  3. DAOを実装するセッションBeanを含むもの

    public EmployeeJpaDAO implements EmployeeDAO {
        interface method implementations here
        ....
        private method that transform my Employee entity into my Employee domain object
    }
    

これで、新しいCRUD操作を実行する必要があるたびに追加する手荷物がたくさんあります。

ただし、DAOを使用することで得られる利点は次のとおりです。

  1. DAOのメモリ内実装を使用して、サービスレイヤーのユニットテストを行うことができます。これは、ビジネスロジックをテストするためにデータベースにアクセスする必要がないことを意味し、オブジェクトには常に同じプロパティの値が含まれることが保証されます。

  2. ビジネスロジックとデータベースアクセスロジックを分離します。

DAOの実装を含まないオプションは、サービスレイヤーでエンティティオブジェクトとEntityManagerを使用することです。

@Stateless
public class EmployeeEjb {
    @PersistenceContext(unitName = "employee")
    private EntityManager manager;

    public Employee getEmployeeById(long id) {
        return manager.createNamedQuery(Employee.GetEmployeeById).getResultList();
    }
    ...
}

ここに中間点はありませんか?上記のDAOレイヤーの利点(最も重要なのはビジネスロジックの単体テスト容易性)のいくつかを満たすアーキテクチャを見つけたり実装したりしている人はいますか?

推奨事項および/または提案をありがとう!これに関して何人かの人々が思いついたことを本当に知りたいです。

46
Brian DiCasa

JPA2のようなORMを使用している場合-データベースにマップされているエンティティがある場合でも、DAOを使用する必要がありますか?オーバーヘッドがはるかに多いようです。

そうです。そして明らかに、Java EEは、JPAを使用するときに [〜#〜] dao [〜#〜] パターンの使用を推奨していません(JPAはすでに標準化された実装を提供しています) ドメインストア パターンであり、DAOの背後でそれをシールドすることにあまり価値がありません。DAOがアンチであることがわかります- [〜#〜] dry [〜#〜] このような状況では。

したがって、simpleの場合(実際には、ほとんどの場合)、DAOは喜んでスキップし、問題はありません。もっとcomplexの場合(たとえば、ストアドプロシージャ、フラットファイルを使用する場合)は、それを使用します。言い換えれば、それは JPAがDAOを殺したか? に要約されているように、依存します。以下の関連質問もご覧ください。

関連する質問

(...)DAOを実装するセッションBeanを含むもの

いいえ、DAOをセッションBeanとして実装したくありません。

  • テーブルほど多くの(プールされた)セッションBeanを作成したくない(リソースの大きな浪費)
  • どこにでもセッションBeanをチェーンしたくない、過去のエラーを再現したくない、これはよくスケールしない既知の悪い習慣です。

したがって、本当にDAOの方法を使い、EMを挿入したい場合は、DAOをSpring Bean(Java EE 5))またはCDI管理Bean(Java EE 6)。

DAOのメモリ内実装を使用して、サービスレイヤーのユニットテストを行うことができます。

unitテストを本当に実行したい場合は、DAO/EntityManagerをモックします。違いはありません。また、統合テストを行う場合は、メモリー内データベースを使用するようにJPAを構成できます。結局のところ、私はこの議論を買わないだけです。

ビジネスロジックとデータベースアクセスロジックを分離します。

正直なところ、DAOとエンティティマネージャーの違いにbigの違いはありません。 」繰り返しますが、私はこの議論を買いません。

そして、私の経験からすると、根本的な永続化ソリューションの変更は非常に例外的なイベントであり、起こりそうもない何かのためにDAOを導入するつもりはありません( [〜#〜] yagni [〜#〜][〜#〜] kiss [〜#〜] )。

ここに中間点はありませんか?上記のDAOレイヤーの利点(最も重要なのはビジネスロジックの単体テスト容易性)のいくつかを満たすアーキテクチャを見つけたり実装したりしている人はいますか?

中立的な立場はあまり見られず、強く示唆されているように、必要性を感じなければDAOを使用しません。そして、先ほど述べたように、ビジネスロジックを本当に単体テストしたい場合は、EntityManagerをモックします。それは私にとってはうまくいき、私はより少ないコードを書いてうれしいです。

その他のリソース

48
Pascal Thivent

記録のために。

単一責任原則(SRP)の場合、DAOは必須であり、モデルとロジックを、容易に移植できる永続化レイヤーで分離します。

プロジェクトがテストユニットを使用している場合、DAOはそれを正しくテストするのに役立ちます(モックアップ、データベーステストなど)。

DAOはサービスであり、サービスと同様に、メンテナンスが簡単な素敵なクラスでプロセスをラップできます。

JPAはコードの行数を減らしますが、それでもなお、古い規則が適用されます。

JPAはリポジトリ層をもたらしますが、そのOURリポジトリ層ではないです。同じ原理で、あるプロセスの利益を得るロジックをカプセル化したとしましょう。カプセル化は単に0.1の乗算ですが、カプセル化する価値があります。

たとえば、次の問題があるとしましょう:奇妙な理由で、データベースに新しいクライアントを挿入できますか?テストはどこから始めればいいですか? a:ClientDaoが存在する場合は存在し、存在しない場合は他の場所で検索してください。

4
magallanes