8

背景: Person ドメイン オブジェクトがあります。集約ルートです。以下のクラスの一部を含めました。

オブジェクトの動作を実行するメソッドを公開しています。たとえば、BankAccount を追加するには、AddBankAccount() メソッドを使用します。クラスのすべてのメソッドを含めたわけではありませんが、すべてのパブリック プロパティはメソッドを使用して更新する必要があるとだけ言っておけば十分です。

CRUD 操作を処理する IPerson リポジトリを作成します。

public interface IPersonRepository
{ 
    void Save(Person p);
    //...other methods
}

質問: 既存の個人を更新する場合、どのフィールドを更新する必要があるかをリポジトリにどのように伝えるのですか? たとえば、既存の人に銀行口座を追加した場合、repository.Save() が呼び出されたときに、この情報をリポジトリにどのように伝達すればよいでしょうか?

リポジトリでは、いつ新しい人が作成されたかを判断するのは簡単ですが、既存の人が存在し、その人のフィールドを更新した場合、これをリポジトリに伝える方法がわかりません。

更新されたフィールドに関する情報で Person オブジェクトを汚染したくありません。

リポジトリに .UpdateEmail()、AddBankAccount() などの個別のメソッドを設定することもできますが、やり過ぎのように感じます。リポジトリに単純な .Save() メソッドが必要で、何らかの方法で何を更新する必要があるかを判断します。

他の人はこの状況にどのように対処しましたか?

ウェブとスタックオーバーフローを検索しましたが、何も見つかりませんでした。DDD パラダイム内での永続性に関して言えば、これは単純なことのように思えるため、正しく検索していないに違いありません。また、DDD についての私の理解がかなりずれている可能性もあります :-)

public class Person : DomainObject
{
    public Person(int Id, string FirstName, string LastName,
        string Name, string Email)
    {
        this.Id = Id;
        this.CreditCards = new List<CreditCard>();
        this.BankAccounts = new List<BankAccount>();
        this.PhoneNumbers = new List<PhoneNumber>();
        this.Sponsorships = new List<Sponsorship>();
    }

    public string FirstName { get; private set; }
    public string LastName { get; private set; }
    public string Name{ get; private set; }
    public string Email { get; private set; }
    public string LoginName { get; private set; }

    public ICollection<CreditCard> CreditCards { get; private set; }

    public ICollection<BankAccount> BankAccounts { get; private set; }

    public ICollection<PhoneNumber> PhoneNumbers { get; private set; }  

    public void AddBankAccount(BankAccount accountToAdd, IBankAccountValidator bankAccountValidator)
    {
        bankAccountValidator.Validate(accountToAdd);

        this.BankAccounts.Add(accountToAdd);
    }

    public void AddCreditCard(CreditCard creditCardToAdd, ICreditCardValidator ccValidator)
    {
        ccValidator.Validate(creditCardToAdd);

        this.CreditCards.Add(creditCardToAdd);
    }

    public void UpdateEmail(string NewEmail)
    {
        this.Email = NewEmail;
    }
4

2 に答える 2

0

この問題を解決するために私がやっていることは、ドメイン オブジェクトにインターフェイスを追加することです。

interface IDirtyTracker {
    bool IsDirty {get;}
    void MarkClean();
    void MarkDirty();
}

基本DomainObjectクラスは を実装できIDirtyTracker、リポジトリなどはIsDirty、それがダーティかクリーンかをチェックするために使用できます。

変更を行う各セッターで:

void SetValue() {
    this._value = newValue;
    this.MarkDirty();
}

これは細かいチェックにはなりませんが、リポジトリ レベルで不要な更新を回避する簡単な方法です。

これを少し簡単にするためGetPropertiesToIncludeInDirtyCheckに、チェックする必要があるプロパティのリストを取得するメソッドを追加できます。

interface IDirtyTracker {
    IENumerable<Object> GetPropertiesToIncludeInDirtyCheck();
}
于 2016-09-29T22:10:01.817 に答える