13

私は最初の DDD プロジェクトに取り組んでおり、エンティティ、データ アクセス オブジェクト、およびそれらの関係の基本的な役割を理解していると思います。各検証ルールをそれに関連付けられたエンティティと共に格納する基本的な検証実装があります。これは、現在のエンティティのみに適用されるルールには問題なく機能しますが、他のデータが必要な場合には機能しなくなります。たとえば、ユーザー名が一意でなければならないという制限がある場合、現在の名前を持つ既存のユーザーが存在する場合に IsValid() 呼び出しが false を返すようにします。

ただし、この検証ルールをエンティティ自体に保持するためのクリーンな方法は見つかりません。エンティティに IsNameUnique 関数を使用したいのですが、これを行うためのほとんどのソリューションでは、ユーザー データ アクセス オブジェクトを挿入する必要があります。このロジックは外部サービスに含める必要がありますか? もしそうなら、どうすればエンティティ自体のロジックを維持できますか? それとも、これはユーザーエンティティの外にあるべきものですか?

ありがとう!

4

3 に答える 3

4

サミュエルの回答は気に入っていますが、シンプルにするために、Specificationを実装することをお勧めします。ブール値を返す仕様を作成して、オブジェクトが特定の基準を満たしているかどうかを確認します。仕様に IUserRepository を挿入し、その名前のユーザーが既に存在するかどうかを確認し、ブール値の結果を返します。

public interface ISpecification<T>
{
  bool IsSatisfiedBy(TEntity entity);
}

public class UniqueUsernameSpecification : ISpecification<User>
{
  private readonly IUserRepository _userRepository;

  public UniqueUsernameSpecification(IUserRepository userRepository)
  {
    _userRepository = userRepository;
  }

  public bool IsSatisfiedBy(User user)
  {
    User foundUser = _userRepository.FindUserByUsername(user.Username);
    return foundUser == null;
  }
}

//App code    
User newUser;

// ... registration stuff...

var userRepository = new UserRepository();
var uniqueUserSpec = new UniqueUsernameSpecification(userRepository);
if (uniqueUserSpec.IsSatisfiedBy(newUser))
{
  // proceed
}
于 2009-06-21T05:41:40.840 に答える
2

DDD には、集約という概念があります。基本的に、アプリケーション内の一貫性に責任があります。

私見、この場合、具体的には、CustomerRepository は「Customer 集約」のようなものの中にあり、Customer クラスが集約ルートであると思います。

ルートは、このすべてのことを行う責任があり、他の誰も CustomerRepository オプションにアクセスできませんでした。そして、いくつかの可能性があります:

  • 名前が一意でない場合、CustomerRepository は例外をスローする可能性があります (そして、Customer はエラーをキャッチして返すか、またはそのようなものです)。
  • CustomerRepository は IsValidUserName() を持つことができ、顧客は他のことを行う前にそれを呼び出します。
  • あなたが考えることができる他のオプション
于 2009-06-15T21:15:05.217 に答える