【发布时间】:2011-02-20 17:44:53
【问题描述】:
我正在尝试了解贫血域模型以及为什么它们被认为是反模式。
这是一个真实的例子。
我有一个 Employee 类,它有很多属性 - 姓名、性别、用户名等
public class Employee
{
public string Name { get; set; }
public string Gender { get; set; }
public string Username { get; set; }
// Etc.. mostly getters and setters
}
接下来,我们有一个系统,该系统涉及在销售人员之间平均轮换来电和网站查询(称为“潜在客户”)。这个系统相当复杂,因为它涉及轮询查询、检查假期、员工偏好等。所以这个系统目前被分离成一个服务:EmployeeLeadRotationService。
public class EmployeeLeadRotationService : IEmployeeLeadRotationService
{
private IEmployeeRepository _employeeRepository;
// ...plus lots of other injected repositories and services
public void SelectEmployee(ILead lead)
{
// Etc. lots of complex logic
}
}
然后在我们的网站查询表的背面,我们有这样的代码:
public void SubmitForm()
{
var lead = CreateLeadFromFormInput();
var selectedEmployee = Kernel.Get<IEmployeeLeadRotationService>()
.SelectEmployee(lead);
Response.Write(employee.Name + " will handle your enquiry. Thanks.");
}
我并没有真正遇到这种方法的很多问题,但据说这是我应该尖叫的东西,因为它是一个贫血域模型。
但对我来说,不清楚线索轮换服务中的逻辑应该去哪里。它应该领先吗?它应该进入员工吗?
轮换服务需要的所有注入的存储库等如何 - 考虑到大多数时候与员工打交道时我们不需要任何这些存储库,它们将如何注入员工?
【问题讨论】:
-
那么
ILead看起来像什么,如果将 .SelectEmployee() 放入其中并不明显? -
好吧,在这种情况下,主要是网络查询,所以它会有一个 Comments 属性等。但我们也有电话查询、应用程序、报价等,它们都略有不同。 ILead 接口将具有 LocationOfLead、TimeOfLead 等属性
-
所以我想将 .SelectEmployee() 放在首位比员工更明显,但这并没有解决其他问题:依赖存储库的注入;缺乏 SoC;在很多时候(例如在报告期间)我们在 Lead 类中包含所有这些 SelectEmployee 代码的总体复杂性(实际上我们需要一个 LeadBase 类,这样我们就不会在所有继承的潜在客户类中重用代码)真的不关心员工是如何被选中的。