Доменный дизайн: как работать со сложными моделями с большим количеством полей данных?
Ну, я пытаюсь применить принципы доменного дизайна для своего приложения с богатой моделью домена, которая содержит как поля данных, так и бизнес-логику. Я прочитал много книг DDD, но кажется, что их модели домена (называемые сущностями) очень просты. Это становится проблемой, когда у меня есть модель домена с 10-15 полями данных, например, ниже:
class Job extends DomainModel{
protected int id;
protected User employer;
protected string position;
protected string industry;
protected string requirements;
protected string responsibilities;
protected string benefits;
protected int vacancy;
protected Money salary;
protected DateTime datePosted;
protected DateTime dateStarting;
protected Interval duration;
protected String status;
protected float rating;
//business logic below
}
Как вы видите, эта модель домена содержит много полей данных, и все они важны и не могут быть снимать. Я знаю, что хорошая богатая модель домена не должна содержать методы сеттера, а скорее передавать свои данные конструктору и мутировать состояния с помощью бизнес-логики. Однако для вышеуказанной модели домена я не могу передать все конструктору, так как это приведет к 15+ параметрам в методе конструктора. Метод не должен содержать более 6-7 параметрам, не так ли?
Итак, что я могу сделать, чтобы иметь дело с моделью домена с большим количеством полей данных? Должен ли я попытаться разложить его? Если и как? Или, может быть, я должен просто использовать класс Builder или отражение для инициализации его свойств при создании экземпляра, чтобы я не загрязнял конструктор таким количеством аргументов? Кто может дать совет? Спасибо.
2 ответов
то, что вы пропустили, - это понятие объекта Value. Объекты Value-это небольшие неизменяемые объекты со значением в соответствующей области.
Я не знаю специфику вашего домена, но глядя на ваши Job
entity, может быть объект значения JobDescription
это выглядит так:
class JobDescription {
public JobDescription(string position, string requirements, string responsibilities) {
Position = position;
Requirements = requirements;
Responsibilities = responsibilities;
}
public string Position {get;}
public string Requirements {get;}
public string Responsibilities {get;}
}
это код C#, но я думаю, что идея должна быть ясной независимо от языка, который вы используете.
основная идея состоит в том, чтобы группа значения таким образом, что имеет смысл в соответствующем домене. Это означает, что объекты value также могут содержать другие объекты value.
вы также должны убедиться, что объекты value сравниваются по значению, а не по ссылке, например, путем реализации IEquatable<T>
В C#.
если вы рефакторинг кода с таким подходом, вы получите меньшее количество полей на сущности, поэтому использование инъекций конструктора (что настоятельно рекомендуется) становится возможным снова.
дополнительные примечания, касающиеся вашего примера кода, которые непосредственно не связаны с вопросом:
The модель предметной области это все, Ан сущность является его частью. Поэтому ваш базовый класс должен называться
Entity
, а неDomainModel
.вы должны сделать свой класс
private
и предоставитьprotected
аксессоры где необходимо поддерживать инкапсуляция.
в вашем объекте модели домена работы происходит очень много-кажется, что он смешивает огромное количество проблем и (по крайней мере, для меня) предлагает ряд ограниченных контекстов, некоторые из которых легко различить ради создания примера.
- вознаграждение (оплата труда, льготы)
- организационная позиция (отчетная строка)
- человек спек (навыки)
- спецификация работу (ответственность)
- etc.
когда вы рассматриваете вещи, которые взаимодействуют с вашей моделью "работы", есть ли необходимость проверять или мутировать как свойство зарплаты, так и отраслевое свойство, например?
Не зная всех нюансов домена, зарплата, которую вы получаете за удержание должности, и отрасль, в которой вы работаете, на самом деле не связаны, не так ли? Не риторический момент; это вопросы, которые вам нужно задать домену экспертный.
Если они не имеют никакого взаимодействия, то вы определили, что эти две вещи существуют в двух разных ограниченных контекстах. Зарплатная сторона не нуждается в каком-либо взаимодействии с отраслевой стороной и наоборот, и даже если бы они и нуждались, нужно ли их держать как государство в одном и том же процессе в одно и то же время?
подумайте о жизненном цикле того, как человек становится сотрудником; человек обращается за работой. Работа имеет спецификацию, диапазон зарплаты. Человек посещает интервью. Наниматели предлагают человеку должность. Человек принимает. Человек теперь работник,а не кандидат. Новый сотрудник теперь начисляет отпуск и льготы и имеет дату начала и т. д.
DDD учит нас, что единый, единый взгляд на мир редко служит какой-либо из проблем правильно. Пожалуйста, исследуйте ограниченные контексты - ваше программное обеспечение будет гораздо более гибким и гибким в результате.