Избежать анемичной модели домена - настоящий пример
Я пытаюсь понять Модели анемичных доменов и почему они предположительно являются анти-шаблонами.
Вот пример реального мира.
У меня есть класс 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]()