あなたは、このようなクラス定義することができますActiveRecordの使用:これはいいとシンプルであるがアクティブレコード対リポジトリ - 賛否両論?
class Contact
{
private String _name;
public String Name
{
get { return _name; }
set
{
if (value == String.IsNullOrWhiteSpace())
throw new ArgumentException(...);
else
_name = value;
}
}
public Boolean Validate() { ... /* check Name is unique in DB */ }
public Boolean Save() { ... }
public static List<Contact> Load() { ... }
}
を、私は私のクラスが起こっロジックの大ミックスで非常に肥大化になることがわかりました!レイヤード/ドメインのデザインを使用して
次のような同じクラスを定義することができます:それはアクティブレコード=>階層化設計から移行された
class Contact
{
[Required(AllowEmptyStrings=false)]
public String Name { get; set; }
}
class ContactService : IService
{
public List<Contact> LoadContacts() { return (new ContactRepository()).GetAll(); }
public Contact LoadContact(int id) { return (new ContactRepository()).GetById(id); }
public Boolean SaveContact(Contact contact)
{
if (new ContactValidator().Validate(contact))
new ContactRepository().Save(contact);
}
}
class ContactRepository : IRepository
{
public List<Contact> GetAll() { ... }
public Contact GetById(int Id) { ... }
public Boolean Save(Contact contact) { ... }
}
class ContactValidator : IValidator
{
public Boolean Validate(Contact contact) { ... /* check Name is unique in DB */ }
}
class UnitOfWork : IUnitOfWork
{
IRepository _contacts = null;
public UnitOfWork(IRepository contacts) { _contacts = contacts; }
public Commit() { _contacts.Save(); }
}
どのように?
-
名セッターで
- エンティティレベルの検証は=>は、新しい別のContactValidator
- 保存ロジックにエンティティから移動(DataAnnotation経由ableit)
- ビジネスロジック/ルールの検証(一意の名前)=>のまま = >
- (またたUnitOfWorkで)別個のリポジトリパターンクラスに移動ロードロジック=>リポジトリと別のリポジトリ
- 相互作用がContactValidator、ContactRepositoryの使用を強制する新しいContactService(UnitOfWorkを介してであるに移動等 - レットインに反対ContactRepositoryで発信者を逃がす!)。
このレイヤードデザインのピアの承認/提案を探しています - 通常、アクティブレコードタイプの外ではデザインしません。コメントは感謝しています。
NB - この例では、意図的に単純です(UnitOfWorkのは実際には使われていないとリポジトリ/検証のNEWINGは異なる方法で処理されるだろう)。