0

かなり長い間私を悩ませてきた次の質問があります。次のドメインエンティティ「連絡先」をモデル化したいと思います:

public class Contact:IEntity<Contact>
{
    private readonly ContactId _Id;
    public ContactId Id
    {
        get { return this._Id; }
    }


    private CoreAddress _CoreAddress;
    public CoreAddress CoreAddress
    {
        get { return this._CoreAddress; }
        set
        {
            if (value == null)
                throw new ArgumentNullException("CoreAddress");
            this._CoreAddress = value;
        }
    }


    private ExtendedAddress _ExtendedAddress;
    public ExtendedAddress ExtendedAddress
    {
        get { return this._ExtendedAddress; }
        set
        {
            if (value == null)
                throw new ArgumentNullException("ExtendedAddress");
            this._ExtendedAddress = value;
        }
    }

    private readonly IList<ContactExchangeSubscription> _Subscriptions
        = new List<ContactExchangeSubscription>();

    public IEnumerable<ContactExchangeSubscription> Subscriptions
    {
        get { return this._Subscriptions; }
    }

    public Contact(ContactId Id, CoreAddress CoreAddress, ExtendedAddress ExtendedAddress)
    {
        Validations.Validate.NotNull(Id);
        this._Id = Id;
        this._CoreAddress = CoreAddress;
        this._ExtendedAddress = ExtendedAddress;
    }
  }

ご覧のとおり、サブスクリプションのコレクションがあります。サブスクリプションは次のようにモデル化されます。

 public class ContactExchangeSubscription
{
    private ContactId _AssignedContact;
    public ContactId AssignedContact
    {
        get { return this._AssignedContact; }
        set
        {
            if (value == null)
                throw new ArgumentNullException("AssignedContact");
            this._AssignedContact = value;
        }
    }

    private User _User;
    public User User
    {
        get { return this._User; }
        set
        {
            Validations.Validate.NotNull(value, "User");
            this._User = value;
        }
    }


    private ExchangeEntryId _EntryId;
    public ExchangeEntryId EntryId
    {
        get { return this._EntryId; }
        set
        {
            if (value == null)
                throw new ArgumentNullException("EntryId");
            this._EntryId = value;
        }
    }


    public ContactExchangeSubscription(ContactId AssignedContact, User User, ExchangeEntryId EntryId)
    {
        this._AssignedContact = AssignedContact;
        this._User = User;
        this._EntryId = EntryId;
    }



}

現在、自分のドメインでストレージ テクノロジ (Exchange) をモデル化するべきではないと考えています。結局、アプリケーションを他のサブスクリプション プロバイダーに切り替えたいと思うかもしれません。プロパティ「EntryId」は Exchange に固有です。ただし、サブスクリプションには常に User と ContactId が必要です。サブスクリプションをモデル化するより良い方法はありますか? 必要に応じて、サブスクリプション タイプにファクトリまたは抽象ファクトリを使用して、他のタイプのサブスクリプションをカバーする必要がありますか?

編集: それでは、リングに抽象ファクトリを投げて、いくつかのインターフェイスを紹介しましょう。

public interface IContactSubscriptionFactory
{
    IContactSubscription Create();
}

public interface IContactSubscription
{
    ContactId AssignedContact { get;}
    User User { get; }
}

ContactExchangeSubscription の具体的なファクトリはどのようにコーディングされますか? このタイプには EntryID フィールドが必要であるため、追加の ctr パラメータを取得する必要があることに注意してください。一般に、工場のさまざまなサブタイプでさまざまなコンストラクターパラメーターを処理する方法は?

4

2 に答える 2

1

答えは、将来的に新しいサブスクリプション プロバイダー(適切な用語であれば)interfaceを導入しやすくすることに反対する必要があるという点で、あなたを直視していると思います。これは、DDD よりも OO 設計の問題だと思います。

public interface ISubscriptionProvider
{
    ContactId AssignedContact { get; }
    User User { get; }
}

そして、契約のコードは次のようになります

private readonly IList<ISubscriptionProvider> _subscriptions
    = new List<ISubscriptionProvider>();

public IEnumerable<ISubscriptionProvider> Subscriptions
{
    get { return _subscriptions; }
}

工場の使用に関して; ファクトリの目的は、作成戦略が必要なときにドメイン オブジェクトを構築することです。たとえば、SubscriptionProviderFactory は、集計を再水和するときにリポジトリ内で使用でき、渡されたデータに基づいて ContactExchangeSubscription (ISubscriptionProvider として) またはその他のものを返すかどうかを決定します。

最後のポイントですが、おそらくこれは、例を示した方法によるものです。しかし、あなたは実際には DDD に従っておらず、振る舞いがなく、すべてのプロパティに公開ゲッターとセッターがあり、Aemic Domain Modelを構築するという罠に陥っていると思います。

于 2012-07-11T06:13:01.400 に答える
0

いくつかの調査の後、私はこれを思いつきました。最初のコード、以下の説明:

public interface IContactFactory<TSubscription> where TSubscription : IContactSubscription
{
    Contact Create(ContactId Id, CoreAddress CoreAddress, ExtendedAddress ExtendedAddress, TSubscription Subscription);
}

public class ContactFromExchangeFactory : IContactFactory<ContactExchangeSubscription>
{
    public Contact Create(ContactId Id, CoreAddress CoreAddress, ExtendedAddress ExtendedAddress, ContactExchangeSubscription ExchangeSubscription)
    {
        Contact c = new Contact(Id, CoreAddress, ExtendedAddress);
        c.AddSubscription(ExchangeSubscription);
        return c;
    }
}

Contactsubscription のファクトリーではなく、contact 自体のファクトリーが必要であることに気付きました。

途中で工場についていくつかのことを学びました。

  • これらは、(実際に) 新しいエンティティを作成する場合にのみ使用され、たとえば SQL DB からエンティティを再構築する場合には使用されません。
  • それらはドメイン層に住んでいます(上記を参照してください!)
  • ファクトリは、データよりも動作が異なる類似のオブジェクトに適しています

コメントとより良い回答を歓迎します。

于 2012-07-12T18:57:51.290 に答える