使用 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(); }
}
它是如何从 Active Record => 分层设计迁移而来的?
- Name setter => 中的实体级别验证仍然存在(通过 DataAnnotation 实现)
- 业务逻辑/规则验证(唯一名称)=> 从实体移动到新的单独 ContactValidator
- 保存逻辑 => 移至单独的存储库模式类(也带有 UnitOfWork)
- 加载逻辑 => 移动到单独的存储库
- 与存储库的交互是通过一个新的 ContactService(它将强制使用 ContactValidator、ContactRepository、UnitOfWork 等 - 反对让调用者与 ContactRepository 松散!)。
我正在为这种分层设计寻找同行的认可/建议——我通常不会在 Active Record 类型之外进行设计!任何评论表示赞赏。
注意 - 这个例子是故意简单的(UnitOfWork 并没有真正使用,并且新的 Repository/Validator 将被不同地处理)。