2

メンバーがアイテムに入札できるアクション Web サイトを作成したいとします。このドメインをモデル化するために、Member、Item、Bid の 3 つのクラスがあります。私のブレインストーミングは次のようになります。

  • アイテムには複数の入札を含めることができます
  • 入札は 1 つのアイテムと 1 つのメンバーに関連付けられます
  • メンバーには複数の入札を含めることができます
  • メンバーとアイテムは入札インスタンスなしで存在できます
  • 入札インスタンスは、メンバーとアイテムの両方なしでは存在できません

これらすべてを考慮すると、Member オブジェクトと Item オブジェクトは独立しているため、それらを集約ルートと見なすことができることは明らかです。入札は、これらの集計の 1 つの一部になります。それは明らかですが、現在私を混乱させているのは、どの集計ルートを選択すればよいのでしょうか? アイテムかメンバーか

これは、Apress による Pro ASP.NET MVC 3 Framework ブックの例であり、彼らが行った方法は次のようなものです。

ここに画像の説明を入力

次のコードが得られます。

public class Member 
{
    public string LoginName { get; set; } // The unique key
    public int ReputationPoints { get; set; }
}

public class Item 
{
    public int ItemID { get; private set; } // The unique key
    public string Title { get; set; }
    public string Description { get; set; }
    public DateTime AuctionEndDate { get; set; }
    public IList<Bid> Bids { get; set; }
}

public class Bid 
{
    public Member Member { get; set; }
    public DateTime DatePlaced { get; set; }
    public decimal BidAmount { get; set; }
}

Member と Item はここでは集約ルートであり、Bid は Item に含まれています。ここで、「特定のメンバーによって投稿されたすべての入札を取得する」というアプリケーションの使用例があるとしましょう。つまり、最初にすべてのアイテムを取得し (たとえば、リポジトリ インターフェイスを介してデータベースから)、一致するメンバーを見つけようとして各アイテムのすべての入札を列挙する必要があるということですか? ちょっと非効率じゃないですか?そのため、Bid オブジェクトを Member 内に集約することをお勧めします。しかし、その場合は、新しいユース ケースを考えてみましょう: 「特定のアイテムのすべての入札を取得する」。ここでも、すべての入札を取得するには、逆の方向に進む必要があります...

アプリケーションでこれらのユース ケースの両方を実装する必要があることを考慮すると、このドメインをモデル化するための正しく効率的な方法は何でしょうか?

4

1 に答える 1

5

ドメインは、実際にはコマンド(CQRS)要件(データの更新/変更)のみを反映する必要があります。「特定のアイテムのすべての入札を取得する」および「特定のメンバーによって投稿されたすべての入札を取得する」というクエリ(データの読み取り、データの更新/変更なし)が必要だと思います。したがって、クエリの実装はコマンドの実装に依存しないため、この「クエリ」はドメインとは関係ありません(コマンドはドメインメソッドを呼び出しています)。これにより、各クエリを効率的な方法で実装する自由が得られます。私のアプローチは、UIに表示したいデータのみを取得する効率的なDBビューを実装することです。次に、BidForItemDto(DTO =データ転送オブジェクト)という新しいクラスを作成します。)そして、DBビューからBidForItemDtoのコレクションにデータをマップします(ADO.NETを介して手動で行うか、NHibernateを使用することができます(推奨、すべてを行います))。2番目のクエリについても同じで、BidPostedByMemberDtoという新しいクラスを作成します。

したがって、必要なクエリである場合は、ドメインを忘れて、UIに表示するデータにすぎないことを認識し、DBから効率的にクエリを実行してください。UIで何らかのアクションを実行した場合(たとえば、ボタンをクリックして入札を行う場合)にのみ、コマンド「入札を行う」が実行されます。このコマンドは、最後にドメインメソッドItem.PlaceBid(メンバーメンバー、日時の日付、小数の金額)を呼び出します。 )。ところで、IMHOは「入札が多い」アイテムであり、ドメインメソッド「入札を配置」は、ロジック全体を正しく実装するために、以前の入札にアクセスする必要があります。入札コレクションをメンバーに配置することは、私にはあまり意味がありません...

私の頭のてっぺんから、DBビューとSQLクエリのいくつかの例:

特定のアイテムのすべての入札を取得します。

create view BidForItemDto
as
select 
    i.ItemId,
    b.BidId,
    b.MemberId,
    b.DatePlaced,
    b.BidAmount     
from Item i
join Bid b ON b.ItemId = i.ItemId

クエリ:

SELECT *
from BidFormItemDto
where ItemId = <provide item id>

特定のメンバーによって投稿されたすべての入札を取得します。

create view BidPostedByMemberDto
as
select 
    m.MemberId,
    b.BidId,
    b.MemberId,
    b.DatePlaced,
    b.BidAmount     
from Member m
join Bid b ON b.MemberId = i.MemberId

クエリ:

SELECT *
from BidPostedByMemberDto
where MemberId = <provide member id>
于 2012-06-18T18:17:16.890 に答える