1

と呼ばれるドメイン サービスがありOrderService、次のsaveOrder()メソッドがあります。

class OrderService
{
    // ...

    public function saveOrder(Order $order)
    {
        $this->orderRepository->add($order);
        // $this->entityManager->flush();

        $this->notificationService->notifyOrderPlaced($order);
    }
}

saveOrder()注文をリポジトリに追加し ( persist()EntityManager を内部的に呼び出します)、注文を NotificationService に渡して、適切な通知 (電子メール、SMS) を送信します。

問題は、NotificationService が通知に含める注文 ID を必要とする一方で、DB に永続化されていない (ID は自動生成される) ため、注文にはまだ ID がないことです。

明らかな解決策は、上記の例のように、EntityManager を OrderService への依存関係として、リポジトリメソッドflush()の直後に渡すようです。add()しかし、私は常に、ドメイン サービスが EntityManager を認識できるようにすることに消極的でした。ドメイン サービスがリポジトリや他のサービスとのみ通信できるようにすることを好みました。

  • EntityManager に依存するドメイン サービスの欠点は何ですか?
  • より良い代替手段はありますか?

注: 私は PHP と Doctrine ORM を使用していますが、Java と Hibernate にも同じ原則が当てはまると思います。

4

1 に答える 1

0

これらのオプションのいずれか (または両方) を検討することをお勧めします。

  • このサービスをドメイン サービスではなくアプリケーション層サービスにします。変更トラッカーはアプリケーションのコンテキストと現在のユース ケースの進行状況を把握している必要があるため、アプリケーション サービスで変更トラッカーを呼び出すことはまったく問題ありません。典型的なアプリケーション サービスは、ビジネス トランザクションをコミットするか、完了時に変更トラッカーに変更を保存するように依頼します。

    ユースケースの途中でデータベースが関与することを懸念している場合は、NHibernate のGuid.Comb 戦略に相当するものを見つけて、データベースにすぐに INSERT を発行せずに ORM に Id を生成させることができるかもしれません。

  • ドメイン イベントを使用します。オーダーが作成されると、それが新しくなったことを世界に知らせることができます。通知サービスはイベントを処理し、適切な通知を送信します。ここにその例があります(ビジネス トランザクションを処理するアプリケーション層サービスも含まれています)。

于 2013-04-02T15:26:23.367 に答える