Проектирование на основе домена: как работать со сложными моделями с большим количеством полей данных?

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

  1. Вознаграждение (оплата, льготы)
  2. Организационная позиция (линия отчетности)
  3. Человек спец (навыки)
  4. Спецификация работы (обязанности)
  5. и т.п.

Когда вы рассматриваете вещи, которые взаимодействуют с вашей моделью "Работа", есть ли какие-либо, которые должны, например, проверять или изменять ОБОИ свойство Salary и свойство Industry?

Не зная полных нюансов домена, зарплаты, которую вы получаете за занятие должности, и отрасли, в которой вы работаете, на самом деле не связаны, не так ли? Не риторический вопрос; Вот вопросы, которые вам нужно задать экспертам по предметной области.

Если они НЕ имеют никакого взаимодействия, то вы определили, что эти две вещи существуют в двух разных ОГРАНИЧЕННЫХ КОНТЕКСТАХ. Зарплатная сторона не нуждается ни в каком взаимодействии с отраслевой стороной, и наоборот, и даже если они это сделали, нужно ли их одновременно удерживать в качестве государства в одном и том же процессе?

Подумайте о жизненном цикле того, как человек становится работником; человек претендует на работу. Работа имеет спецификацию, диапазон заработной платы. Человек посещает интервью. Наниматели предлагают человеку должность. Человек принимает. Человек теперь работник, а не кандидат. Новый сотрудник теперь получает отпуск и пособия, имеет дату начала и т. Д.

DDD учит нас тому, что единый, единый взгляд на мир редко служит ЛЮБОЙ из проблем правильно. Пожалуйста, изучите связанные контексты - в результате ваше программное обеспечение станет более гибким и гибким.

Другие вопросы по тегам