9

集約 root内にあるエンティティーを参照する適切な方法を見つけることに行き詰まっています。URL パラメーターからのIDしか取得していない場合です。値オブジェクトに焦点を当てた前の質問をしたので、ここで別の例から始めます。

OrderLinean内の anを変更したいとしましょうOrder:

  • ユーザーは、注文の概要とそのすべての注文明細を確認できるページに移動します。
  • ユーザーは、注文明細の横にある編集ボタンをクリックします。
  • 彼は指示されますedit-order-line?orderId=x&orderLineId=y

OrderLine の数量を更新する必要がある場合は、次のようにします。

Order order = orderRepository.find(orderId);
order.updateQuantity(orderLineId, 2);

しかし、ID によって自分自身の一部を取得する責任をオーダーに任せるという考えにはあまり満足できません。この件に関する私の見解は、ドメイン内ではオブジェクトとだけ話すべきであり、ID とは決して話すべきではないということです。Id はユビキタス言語の一部ではありません。ID はドメインの外、たとえば Controller 内に存在する必要があると思います。

次のようなものを使用すると、より自信が持てます。

Order order = orderRepository.find(orderId);
OrderLine orderLine = em.find(OrderLine.class, orderLineId);
order.updateQuantity(orderLine, 2);

Entity Manager と直接対話するという考えも好きではありませんが。リポジトリと集約ルートの責任をバイパスしているように感じます (潜在的に、OrderLine と直接対話できるため)

それをどのように回避しますか?

4

3 に答える 3

13

私の意見では、このアプローチには何も問題はありません。

Order order = orderRepository.find(orderId);
order.updateQuantity(orderLineId, 2);

orderLineId「ローカルアイデンティティ」です。これは集約ルートに固有のものであり、それ以外では意味がありません。「id」と呼ぶ必要はありません。「注文明細番号」でもかまいません。エリック・エヴァンの本から:

境界内の ENTITIES には、AGGREGATE 内でのみ一意のローカル ID があります。

...データベースクエリで直接取得できるのは、AGGREGATE ルートのみです。他のすべてのオブジェクトは、関連付けをたどって見つける必要があります。

于 2011-09-05T17:10:31.190 に答える
1

OrderLineId とは正確には何ですか? 意味がありません。PRODUCT の数量を更新しており、それを ID として使用する必要があります。

Order order = orderRepository.find(orderID);
order.updateQuantity(productID, 2);
于 2011-11-20T18:12:49.540 に答える
0

集約ルートはコンテキストにバインドされます。コンテキストではオーダーはAR であるため、直接公開しているので直接更新しても問題ありません。そのコードが他のエンティティに影響を与える場合は、オーダー AR に存在する必要があります。

より純粋なアプローチが必要な場合は、AR で findByOrderId を作成して完全にロードするか、アプリケーションで OrderLine と OrderId を公開する必要があります (次に、2 番目のアプローチを使用します)。

于 2011-09-05T16:51:55.160 に答える