Проектирование на основе домена: как работать со сложными моделями с большим количеством полей данных?
Ну, я пытаюсь применить принципы доменного проектирования для своего приложения, используя богатую модель предметной области, которая содержит как поля данных, так и бизнес-логику. Я читал много книг 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 ответа
То, что вы пропустили, это концепция объекта значения. Значимые объекты - это небольшие неизменные объекты со значением в соответствующей области.
Я не знаю специфику вашего домена, но, глядя на ваш Job
сущность, может быть объект значения 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#, но я думаю, что идея должна быть ясной независимо от того, какой язык вы используете.
Основная идея состоит в том, чтобы сгруппировать значения таким образом, чтобы это имело смысл в соответствующей области. Это, конечно, означает, что объекты-значения также могут содержать другие объекты-значения.
Вы также должны убедиться, что объекты-значения сравниваются по значению, а не по ссылке, например, путем реализации IEquatable<T>
в C#.
Если вы реорганизуете свой код с помощью этого подхода, вы получите меньше полей в вашей сущности, поэтому использование внедрения в конструктор (что настоятельно рекомендуется) снова становится возможным.
Дополнительные примечания относительно вашего примера кода, которые не связаны напрямую с вопросом:
Модель предметной области - это целое, сущность является ее частью. Итак, ваш базовый класс должен называться
Entity
и неDomainModel
,Вы должны сделать поля вашего класса
private
и предоставитьprotected
средства доступа, где требуется для поддержания инкапсуляции.
В вашем объекте модели домена Job происходит очень многое - он, кажется, смешивает огромное количество проблем и (по крайней мере, мне) предлагает несколько ограниченных контекстов, некоторые из которых легко различить для создания пример.
- Вознаграждение (оплата, льготы)
- Организационная позиция (линия отчетности)
- Человек спец (навыки)
- Спецификация работы (обязанности)
- и т.п.
Когда вы рассматриваете вещи, которые взаимодействуют с вашей моделью "Работа", есть ли какие-либо, которые должны, например, проверять или изменять ОБОИ свойство Salary и свойство Industry?
Не зная полных нюансов домена, зарплаты, которую вы получаете за занятие должности, и отрасли, в которой вы работаете, на самом деле не связаны, не так ли? Не риторический вопрос; Вот вопросы, которые вам нужно задать экспертам по предметной области.
Если они НЕ имеют никакого взаимодействия, то вы определили, что эти две вещи существуют в двух разных ОГРАНИЧЕННЫХ КОНТЕКСТАХ. Зарплатная сторона не нуждается ни в каком взаимодействии с отраслевой стороной, и наоборот, и даже если они это сделали, нужно ли их одновременно удерживать в качестве государства в одном и том же процессе?
Подумайте о жизненном цикле того, как человек становится работником; человек претендует на работу. Работа имеет спецификацию, диапазон заработной платы. Человек посещает интервью. Наниматели предлагают человеку должность. Человек принимает. Человек теперь работник, а не кандидат. Новый сотрудник теперь получает отпуск и пособия, имеет дату начала и т. Д.
DDD учит нас тому, что единый, единый взгляд на мир редко служит ЛЮБОЙ из проблем правильно. Пожалуйста, изучите связанные контексты - в результате ваше программное обеспечение станет более гибким и гибким.