私のプログラミング言語はC#です。ドメインモデル内で永続性の無知に関する質問があります。永続的な無知のドメイン層
のは、私はそうのような人のクラスを持っていると仮定しましょう:
public class Person
{
private string email;
public string Email
{
get { return email; }
set { email = value; }
}
public Person(string email)
{
this.email = email;
}
}
さて、私のドメインモデル内で、同じメールアドレスを持つ二人がすることができないというルールがあります。したがって、新しい人物をインスタンス化するときは、電子メールのプロパティを変更するときだけでなく、検証する必要があります。だから私はあなたが永遠の無知のドメイン層内でそのような検証を解決する方法を考えていた。私が現在行っていることは、人間のインスタンスリポジトリを注入するためのファクトリパターンを使用することです。そこに私は同じ電子メールアドレスを持つ他の人を検索することができます。これと同じように:
public class PersonFactory
{
private static readonly IPersonRepository personRepository;
public Person CreateNewPerson(string email)
{
Person personWithSameMail = personRepository.GetPersonByEmail(email);
if (personWithSameMail != null)
throw new ApplicationException("Email already exists.");
return new Person(email);
}
public PersonFactory(IPersonRepository personRepository)
{
this.personRepository = personRepository;
}
}
しかし、このソリューションを使用して、(有効なビジネスケースもできる)者の電子メールアドレスを変更し、チェックがまだカバーされていません。さらに、Personクラスはまだ公共のコンストラクタを公開しており、工場をバイパスしても、重複した電子メールアドレスを持つ人は引き続き可能です。
これに対する任意の解決策はありますか?
P.S.すべてのデータに中心の人:いいえ、私はデータアクセス層にだまされやすい人の電子メールを検証する必要はありません。)
UPDATE:
おそらく、この全体の問題はとにかく廃止されました。ドメインモデルの文脈の点で重複した電子メールをチェックするには、常にすべての人物、すなわちルートを意識した「何か」が必要です。 「何か」は、アドレス帳、または電子メールアドレスを持つすべての人を含む全世界である可能性があります。だから、おそらく私は、プログラマーが技術的に洗練された問題解決の必要性を混ぜ合わせているのかもしれません。これはここに当てはまりますか?スペースの中に浮かんでいる電子メールアドレスを持つ人だけではないということです(ちょっと、スペースは私の根源になります)。しかし、これがアドレス帳アプリケーションのような本当のビジネスケースであれば、アドレス帳は人の集約ルートとなり、電子メールアドレスが重複しないように内部コレクションのすべての人物をチェックすることができます。
コンストラクタを内部で作成し、更新時に電子メールアドレスも確認してみませんか?そして私はそれが工場にリポジトリを与えるのはいい解決策だとは思わない。ファクトリを呼び出すサービス関数は、電子メールアドレスがすでに存在するかどうかを確認する必要があります。 –
@WouterdeKort:私はあなたのコメントに同意しません:(1)ctorを内部的にすることは何の助けにもなりません。重複したメールアドレスを持つユーザーを作成することはできます。 (2)工場を呼び出すメソッドをチェックすると、そのビジネスルールが効果的に削除されます。このルールを適用するのは呼び出し側の責任です。それはちょうど非常に貧弱なAPIデザインです。 –
@DanielHilgarth彼は、公共のコンストラクタが問題であることを明示しています。ファクトリは、すべての依存関係と必要な値を持つオブジェクトを作成する必要があります。工場とビジネスロジックを混在させることは、私が悪いデザインと呼ぶものです。 –