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

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


в вашем объекте модели домена работы происходит очень много-кажется, что он смешивает огромное количество проблем и (по крайней мере, для меня) предлагает ряд ограниченных контекстов, некоторые из которых легко различить ради создания примера.

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

когда вы рассматриваете вещи, которые взаимодействуют с вашей моделью "работы", есть ли необходимость проверять или мутировать как свойство зарплаты, так и отраслевое свойство, например?

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

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

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

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