Избежать анемичной модели домена - настоящий пример

Я пытаюсь понять Модели анемичных доменов и почему они предположительно являются анти-шаблонами.

Вот пример реального мира.

У меня есть класс 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.");
}

Я не сталкиваюсь с множеством проблем с этим подходом, но, предположительно, это то, над чем я должен запускать крик, потому что это модель анемичного домена.

Но для меня неясно, куда должна идти логика в ведущей службе ротации. Должно ли это идти впереди? Должно ли это идти на работу?

Как насчет всех внедренных репозиториев и т.д., которые требуется службе ротации, - как они будут вставляться в сотрудника, учитывая, что большую часть времени, когда мы имеем дело с сотрудником, нам не нужны какие-либо из этих репозиториев?

Ответ 1

В этом случае это не является моделью анемического домена. Модель анонимного домена специально о проверке и преобразовании объектов. Таким образом, пример может быть, если внешняя функция фактически изменила состояние Работников или обновила их детали.

что происходит в этом случае, вы принимаете всех сотрудников и делаете выбор одного из них на основе их информации. Хорошо иметь отдельный объект, который исследует других и принимает решения относительно того, что он находит. Это НЕ нормально иметь объект, который используется для перехода объекта из одного состояния в другое.

Примером модели анодного домена в вашем случае будет внешний метод

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

который принимает объект Employee и обновляет часы работы в течение недели, убедившись, что флаги подняты, если часы превышают определенный предел. Проблема заключается в том, что если у вас есть только объекты Employee, вы не знаете, как изменить их часы в рамках правильных ограничений. В этом случае способ борьбы с ним заключается в перемещении метода updateHours в класс Employee. В этом и состоит суть анти-модели Anemic Domain Model.

Ответ 2

Я думаю, что ваш дизайн здесь прекрасен. Как вы знаете, анти-шаблон аномальной модели домена - это обратная реакция против тенденции избегать любого поведения, закодированного в объектах домена. Но, наоборот, это не означает, что все поведение, связанное с объектом домена, должно быть инкапсулировано этим объектом.

Как правило, поведение, которое неотъемлемо связано с объектом домена и полностью определяется терминами этого экземпляра объекта домена, может быть включено в объект домена. В противном случае, чтобы четко разъяснить обязанности, лучше всего использовать его во взаимодействии или служении, как вы это делали.

Ответ 3

Все это в вашей голове - рассмотрите сервис ротации, чтобы быть частью модели домена, и проблема растворяется.

Вращение должно содержать информацию о многих сотрудниках, поэтому оно не относится ни к ни одному, ни к одному объекту сотрудника. Он заслуживает того, чтобы быть объектом домена сам по себе.

Просто переименование "RotationService" на что-то вроде "Organization.UserSupportDepartment" делает его очевидным.

Ответ 4

Если ваша модель домена содержит только роли и вещи, а не действия как поведение, то это анемия. Однако я говорю о поведении в отношении модели, а не объекта. Я говорю о различии между ними в другом ответе... fooobar.com/info/83514/...

Из вашего вопроса вы нарушаете мои первые два правила моделирования домена: -

  • Поведение, моделируемое как (записано). Действия лежат в основе модели домена. Добавьте их первым.
  • Операции с моделью домена как классы, а не методы.

Я бы добавил к модели операцию "Запрос". При этом модель имеет поведение и может комбинировать и работать как группа объектов без внешнего контроллера или script.

EnquiryHandlerModel