web-dev-qa-db-ja.com

DAO、DDDのリポジトリとサービス

いくつかの記事を読んだ後、DAOとリポジトリの違いを理解し始めていますが、リポジトリとサービスの違いを理解しようとすると困ります。

簡単に言えば、OOパラダイム:

  • [〜#〜] dao [〜#〜]:1つのエンティティクラスの基本CRUD operationsを含むクラス。基盤となる永続ストレージシステムのものを取得または取得するために必要なコードが含まれています。一般的に、メソッドはオブジェクトエンティティをパラメーターとして受け取ります。ただし、識別子のタイプの使用が有効なretrieveメソッドを除きます。

  • Repositories:抽象化のより高いレベルで..一般的に読んだように、集約オブジェクト(オブジェクト子オブジェクトがあります)。 DAOsを使用してデータベースからオブジェクトを取得し、最終的にはドメイン「ビジネス」言語でインターフェイスを公開します。 (ただし、IDのデータ型を使用することは非常に有効だと思います)。例:非常に単純なaddSomethingで、somethingは、インスタンスによってリポジトリが全体として管理される親の子オブジェクトです。

  • Services:繰り返しますが、より高い抽象化レベルです。私の謙虚な見方をすれば、親子関係を共有しない2つのクラスを接続するのに適した場所ですが、(抽象用語では)リポジトリと同じくらいです。例:2つのbank accounts間のメソッドtransferCash

だから、それは私の読書です、しかし、私はここで上記の考えが正しいかどうか尋ねています。または私がどう考えるべきか。または、これらすべての概念の違いを本当に理解するように私を指すもの。

ソースの一部:

30
Victor

リポジトリは-あなたが言うように-抽象化です。それらは、Martin Fowlerの Object Query Pattern に由来します。リポジトリとDTOはどちらも、永続化されたデータをエンティティオブジェクトの同等のコレクションにマッピングすることにより、データベースの永続化を簡素化できます。ただし、リポジトリは Aggregate Root(AG) の制御を提供することにより、DAOよりも粒度が粗く、多くの場合、クライアントから多くの内部状態を隠します。一方、DAOは、単一のエンティティオブジェクト専用であるのと同じくらいきめ細かいものにできます。リポジトリとDAOの両方で、独自の実装を記述する代わりに Hibernate または他のオブジェクト/リレーショナルマッピング(ORM)フレームワークを使用するのが一般的です。

通常、サービスはサービスレイヤーに常駐でき、機能ファサード、腐敗防止レイヤー、およびキャッシュとトランザクションのコーディネーターの両方として機能できます。多くの場合、ログを記録するのに適した場所です。粗粒度でユースケース指向のサービス。 Service.updateCustomerAdress()またはService.sendOrder()。リポジトリは、クライアントが消費するには細かすぎる場合があります。 Customer.add(…)Order.modify(…)

リポジトリとDAOの目的は同じです。つまり、データを永続的に保持します。一方、サービスは永続性について無知であり、データベースに関する知識がない必要があります。通常、これらはドメインサービス、リポジトリ、ドメインコアと緊密に連携します。

23
Magnus Backeus

リポジトリは、単一のエンティティではなく、 Aggregate Roots(AR) を保存および取得するためのインターフェイスです。ドメインモデルのARごとに1つのリポジトリがあります。

Fowlerの Repository Pattern によると、リポジトリはインメモリオブジェクトコレクションのように機能し、これはDAOと比較する主な違いの1つです。

リポジトリインターフェイスは、ドメインモデルのクライアント(したがってドメインモデルの一部)がドメインモデルの操作を開始するための手段です。クライアントは、リポジトリからARインスタンスを取得し、通常は内部状態を変更するメソッドを呼び出してから、リポジトリに保存することを目的としています。

14
Enrico Sanguin

「DAO」とは何なのかわかりません。リポジトリは、エンティティをロードするための抽象化です。エンティティを取得して保存できるようにする必要があります。クエリなし。一部のデータをクエリする場合は、クエリを作成します(MVCアクションメソッド内、または最も単純で単純な抽象化を使用して、SQLを実行し、HTMLに直接レンダリングできるDTOを返します)。

一方、サービスには注意が必要です。最初は用語が過負荷になっています。 Eric EvansのDDD本 で定義されている「アプリケーションサービス」は、ドメインモデルのオブジェクトがデータベース、メッセージング、キャッシングなどのインフラストラクチャの懸念にアクセスすることを許可されていないために存在します。それらをプレートで渡して、アプリケーションサービスがまさにそれを行います。アプリケーションサービスの部分には、ロジックが含まれていません。私はICustomerService.ChangeAddress()が他の何かをすることを期待しないでしょう:

  1. Customerエンティティをロードします。
  2. Customer.ChangeAddress(newAddress)を呼び出す<-これはドメインロジックをカプセル化します
  3. 顧客を保存します。
  4. おそらくいくつかのイベントを公開します。

顧客をロードし、Addressプロパティを設定して保存するサービスがある場合、そのサービスは実際にはトランザクションスクリプトであり、顧客はDTOです。つまり、漏れやすい抽象化があり、貧弱なドメインモデルを持っている可能性があります。ドメインモデルオブジェクトにはパブリックセッターを含めるべきではありません。また、DDDをCQRSと組み合わせると、ドメインモデルにはメインエンティティID値以外にパブリック状態がまったくない場合があります。

3
Neil Barnwell