【发布时间】:2013-01-11 10:36:17
【问题描述】:
假设您有一个贫血的域模型 (ADM):
public class Employee
{
public Employee()
{
_roles = new List<Role>();
}
private IList<Role> _roles;
public Guid Id { get; set; }
public string Name { get; set; }
public IList<Roles> Roles { get { return _roles; } }
}
public class EmployeeManager
{
public Employee GetByName(string name)
{
Contract.Requires(name != null);
return repositoryOfEmployeesInstance.GetByName(name);
}
public void AddEmployee(string name)
{
Contract.Requires(name != null);
// The unique identifier will be generated by the OR/M behind the scenes...
repositoryOfEmployeesInstance.Add(new Employee { Name = "Matias" });
}
}
稍后,在其他地方,你有这段代码:
Employee some = new EmployeeManager().GetByName("Matias");
some.Roles.Add("Principal");
现在,除了域模型之外,还有一个称为 DomainValidationAspect 的方面,它会在新员工将被持久化到 Repository 实现之前对其进行验证。
整个ValidateEmployeeAspect 可以在添加或更新Employee 时验证它,这是添加角色的情况。它负责加载Employee 的域规则并对其进行验证。域规则使用规范模式实现。
最后,一切都发生在域事务中。
是的,从面向对象编程的角度来看,它似乎是一个贫乏的领域模型,但是面向方面编程呢?
所以问题是……
...领域驱动的设计可能只是因为:
- ...在这种情况下,
Employee角色是使用集合接口添加的? - ...从纯面向对象编程的角度来看,
Employee中没有行为?
一些话
我的观点是,面向方面的编程确实有一个缺点,即在领域的主要流程(或任何其他层)中隐藏了很多细节,但对面向对象背后的概念有一个鸟瞰加面向方面的方法将映射到一个丰富的域模型,而不是一个贫乏的域模型。
【问题讨论】:
-
Aspects 可能是记录日志或错误处理的好方法,但您确定它们是实现实体验证的最有效方式吗?此外,在富域模型中,实体比验证要多得多……您可能需要的特定域方法呢?你也会把它们放在一个方面吗?
-
@guillaume31 不,我不会在某个方面实现域方法,而是在域管理器类中实现。
-
对于包含持久性逻辑加上每个特定于其实体的域方法的管理器,我不知道你的域模型是否贫血,但它肯定会受到 的影响附属物肥大 :)
-
据我了解,贫血域被认为是一种反模式,因为它以没有充分利用 OOP 提供的优势的方式组织代码。请参阅 martinfowler.com/bliki/AnemicDomainModel.html。只要您知道您的方法的缺点并相信它们是可以接受的,那么您应该做适合您的事情。归根结底,这一切都取决于您是否以对您来说物有所值的成本实现了您想要的收益。
-
@AaronHawkins 我知道整篇文章。顺便说一句,我倾向于认为有很多方法可以充分利用 OOP,其中一种可能是我的方法,它利用 AOP 来处理一些可以直接在域对象中实现的东西。好吧,这真的可以以很长的讨论结束……我知道。
标签: c# oop domain-driven-design domain-model aop