避免贫血领域模型-一个真实的例子 [英] Avoiding anemic domain model - a real example

查看:244
本文介绍了避免贫血领域模型-一个真实的例子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解贫血领域模型以及为什么它们被认为是反模式.

I am trying to understand Anemic Domain Models and why they are supposedly an anti-pattern.

这是一个真实的例子.

我有一个Employee类,它具有大量的属性-名称,性别,用户名等

I have an Employee class, which has a ton of properties - name, gender, username, etc

public class Employee
{
    public string Name { get; set; }
    public string Gender { get; set; }
    public string Username { get; set; }
    // Etc.. mostly getters and setters
}

接下来,我们有一个系统,该系统涉及在销售人员之间平均轮流传入电话和网站查询(称为潜在客户").该系统非常复杂,因为它涉及循环查询,检查假期,员工喜好等.因此,该系统目前被分离为一项服务:EmployeeLeadRotationService.

Next we have a system that involves rotating incoming phone calls and website enquiries (known as 'leads') evenly amongst sales staff. This system is quite complex as it involves round-robining enquiries, checking for holidays, employee preferences etc. So this system is currently seperated out into a service: 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
     }
}

然后,在我们的网站查询表单的背面,我们具有以下代码:

Then on the backside of our website enquiry form we have code like this:

public void SubmitForm()
{
    var lead = CreateLeadFromFormInput();

    var selectedEmployee = Kernel.Get<IEmployeeLeadRotationService>()
                                 .SelectEmployee(lead);

    Response.Write(employee.Name + " will handle your enquiry. Thanks.");
}

这种方法并没有真正遇到很多问题,但是应该说,这是我应该大呼过瘾的东西,因为它是一个 Anemic Domain Model (贫血域模型).

I don't really encounter many problems with this approach, but supposedly this is something that I should run screaming from because it is an Anemic Domain Model.

但是对我来说,线索转换服务中的逻辑应该去哪里还不清楚.它应该领先吗?应该在员工身上吗?

But for me its not clear where the logic in the lead rotation service should go. Should it go in the lead? Should it go in the employee?

轮换服务需要所有注入的存储库等吗-考虑到大多数时候与员工打交道,我们不需要这些存储库,如何将它们注入员工?

What about all the injected repositories etc that the rotation service requires - how would they be injected into the employee, given that most of the time when dealing with an employee we don't need any of these repositories?

推荐答案

在这种情况下,这并不构成贫血域模型. Anemic域模型是专门用于验证和转换对象.因此,举一个例子,如果外部函数实际上改变了Employees的状态或更新了其详细信息.

In this case this doesn't constitute an Anemic Domain Model. An Anemic Domain Model is specifically about validating and transforming the objects. So an example of this would be if an external function actually changed the state of the Employees or updated their details.

在这种情况下,您正在带走所有雇员,并根据他们的信息选择其中一个.最好有一个单独的对象来检查其他对象并根据发现的内容做出决定.拥有用于将对象从一种状态转换为另一种状态的对象并不是一件好事.

what is happening in this case is you are taking all of the employees and making a selection of one of them based on their information. It is fine to have a separate object that examines others and makes decisions with regard to what it finds. It is NOT ok to have an object that is used to transition an object from one state to another.

您所遇到的一个贫血域模型的示例是使用外部方法

An example of an Anemic Domain Model in your case would be to have an external method

updateHours(Employee emp) // updates the working hours for the employee

,它接受一个Employee对象并更新其一周的工作时间,并确保如果工作时间超过特定限制,则引发标志.这样做的问题是,如果只有Employee对象,那么您将不知道如何在正确的约束范围内修改其工作时间.在这种情况下,处理该问题的方法是将updateHours方法移到Employee类中.这就是贫血域模型"反模式的症结所在.

that takes an Employee object and updates its hours worked for the week, making sure that flags are raised if the hours exceed a certain limit. The problem with this is that if you only have Employee objects then you have no knowledge of how to modify their hours within the correct constraints. In this case the way to deal with it would be to move the updateHours method into the Employee class. That is the crux of the Anemic Domain Model anti pattern.

这篇关于避免贫血领域模型-一个真实的例子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆