DDD: как слои должны быть организованы? - PullRequest
33 голосов
/ 04 мая 2011

Я очень новичок в разработке программного обеспечения. Лично я считаю, что многоуровневая архитектура - это отличный способ уменьшить сложности, возникающие в процессе разработки программного обеспечения, в объектно-ориентированном подходе и, не говоря уже о том, чтобы сохранить ваш код организованным. Теперь я столкнулся с некоторыми проблемами, которые будут представлены в DDD (Domain Driven Design). Конечно, для начинающих.
Вот оно -
Скажем, я хочу создать приложение для сохранения данных, относящихся к «человеку», в базе данных и отображения информации о человеке в сетке данных wpf (DDD определенно не для приложений такого масштаба, а просто для простоты для такого любителя, как я) , Итак, я разработал домен класса «Персона», что-то вроде -

public class Person
 {
    public Person(dataType paramA, dataType paramB)
    {
        _fieldA = paramA;
        _fieldB = paramB;
    }

    private dataType _fieldA;
    public dataType PropertyA
    {
        //encapsulates _fieldA    
    }

    private dataType _fieldB;
    public dataType PropertyB
    {        
        //encapsulates _fieldB    
    }

    public dataType PropertyX
    {        
        //some code based on private fields    
    }

    public dataType PropertyY
    {        
        //some code based on private fields    
    }

    private dataType MethodPQR(dataType param)
    {        
        //some code    
    }

    public dataType MethodUVW(dataType paramOne, dataType paramTwo)
    {        
        //some code    
    }
}

Теперь, мое понимание DDD говорит, что архитектура (самая простая версия) должна быть следующей (пожалуйста, поправьте меня, если я ошибаюсь) -
enter image description here
Примечание:

  1. Я хочу, чтобы сетка данных была привязана к некоторой ObservableCollection, просто чтобы мгновенно отражать любые изменения.

  2. Это приложение wpf, но оно не обязательно должно быть в шаблоне MVVM, и я намеренно хочу использовать код позади (я понятия не имею, представляет ли код позади себя уровень приложения)

Так что мои вопросы -

  1. Какие коды должны принадлежать прикладному уровню?

  2. Полагаю, мне не следует связывать ObservableColletion моего доменного объекта (Person) в качестве itmsSource для сетки данных. Какой тип объекта тогда я должен извлечь из объекта домена и как?

  3. Чтобы сохранить развязку между объектами Presentation Layer и объектом Domain Layer, может существовать соглашение, подобное “never instantiate domain objects directly in presentation layer”. Каковы тогда не «прямые» подходы?

  4. Если Code-Behind взаимодействует с прикладным уровнем, то должен ли прикладной уровень взаимодействовать с репозиторием? Но что, если нужен какой-то доступ к домену, который не связан с доступом к данным (может быть, не в этом приложении, но это может произойти, не так ли?) поговорить с?

Я знаю, что все мои вопросы и проблемы очень любительского уровня. Но это действительно вопросы и проблемы. Так что, если у кого-то есть время, мы будем благодарны за любой ответ.

РЕДАКТИРОВАТЬ: Я не уверен, что хранилище данных должно иметь ссылку на модель домена.

1 Ответ

38 голосов
/ 05 мая 2011

Говоря в терминах более «классического» DDD, да, доменные объекты обычно не разрешены где-либо за пределами домена. Но не является абсолютным правилом, что доменные объекты не используются на уровне представления. Например, Naked Objects представляет школу мысли, где доменные объекты используются непосредственно. Я сам придерживаюсь в основном философии, согласно которой доменные объекты не используются напрямую, поэтому я не знаком со всеми практиками, которые они предлагают, я лично думаю, что связывание с доменным объектом напрямую не рекомендуется, но ... Просто имейте в виду не все рассматривают это как требование.

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

Предполагается, что бизнес-логика реализована в модели предметной области, поэтому большая часть того, что находится на прикладном уровне, связана с координацией различных служб, обычно для доставки данных в клиентские приложения и из них. Многие люди используют для этого какую-то форму SOA или, по крайней мере, веб-сервисы. Они вызывают репозитории, но также требуют, чтобы другие компоненты, такие как ассемблеры, принимали объекты домена, возвращенные из вызовов репозитория, и копировали значения свойств в DTO, которые затем сериализуются и возвращаются вызывающей стороне. Вызывающая сторона часто является докладчиком или контроллером, но если вы не используете MVC или MVP, вызывающая сторона все равно будет находиться на уровне представления. Обратное отключение является более сложным - пользовательский интерфейс может отправлять обратно DTO, которые представляют обновления, или DTO, которые представляют новые объекты, которые будут добавлены. Посредничество между этими действиями является в первую очередь целью прикладного уровня.

Что касается «отсутствия доступа к данным» на уровне домена, есть пара типичных примеров. Большинство людей обычно ссылаются на компонент «X», который вы можете рассматривать как доменную службу. Служба домена отличается от службы приложений своей близостью к модели домена и наличием реальной бизнес-логики.

Например, если приложение предполагает какое-либо размещение заказа, на самом деле есть две проблемы - размещение заказа и его выполнение. Службы приложений обеспечивают передачу данных, необходимых для формулирования размещения заказа, в пользовательский интерфейс, а затем возвращают заказ, который пользователь хочет разместить. Но это только передача данных, и на этом службы приложений заканчиваются. В этом случае может потребоваться доменная служба, чтобы применять бизнес-правила и создавать дополнительные доменные объекты, необходимые для фактического выполнения этого заказа.

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

Единственный другой режим «доступа», отличный от ориентированного на данные, с которым я сталкивался или легко могу представить, - это ориентированная на процесс функциональность. Это встречается не во всех приложениях, но распространено в определенных областях. Например, в сфере здравоохранения, где я работаю, вам могут потребоваться приложения, которые включают в себя важные элементы управления как клиническими данными, так и клиническим процессом. Я решаю эту проблему, не делая акцент на этом процессе частью моей предметной модели, и вместо этого использую различные инструменты.

Методы ООП не очень подходят для самого процесса, они полезны для предоставления данных и сбора данных из процесса.Объектно-ориентированный, в конце концов, также в первую очередь ориентирован на существительное.Для управления процессами в реальном времени вам нужно больше «ориентированное на глагол программирование», чем «ориентированное на существительное».Инструменты рабочего процесса являются инструментами, ориентированными на глаголы, которые могут дополнять модели, управляемые доменом, для приложений, которые интенсивно используют данные и процессы.Я выполняю большую работу, которая включает в себя как модели C # DDD, так и модели Workflow Foundation, но, опять же, это необходимо только для определенных типов приложений.Для многих типичных бизнес-приложений требуются только доменные модели и сервисы.

Наконец, наиболее важным аспектом DDD является не какая-либо техника или архитектура.Настоящее сердце вращается вокруг повсеместно распространенного языка и взаимодействия с (по моему убеждению, НЕПОСРЕДСТВЕННЫМ взаимодействием) с экспертами в предметной области, чтобы получить критически важные знания в предметной области.(Большинство компаний, которые утверждают, что используют DDD, по моему мнению, не делают этого, потому что очень много компаний отказываются разрешить бизнесу и развитию напрямую взаимодействовать, но это другая тема ...) Это извлечение и включение знаний предметной области, а не любаяметод, который фактически отделяет DDD от обычного ООП, и именно здесь возникает реальное значение DDD.

EDIT

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

OTOH на уровне домена обычно не взаимодействует с репозиториями.Как правило, вы хотите, чтобы модель предметной области была автономной и отделенной от какой-либо конкретной технологии, то есть она должна представлять «чистое знание предметной области».Постоянство по своей сути тесно связано с какой-то конкретной технологией, поэтому в целом люди стремятся сделать свои доменные модели свободными от какой-либо постоянной реализации.У вас есть репозитории, но вы обычно не хотите вызывать методы репозитория в доменной модели.

Внутри самой доменной модели объекты получаются либо в виде новых объектов (которые могут быть созданы непосредственно или через фабрику), либо в других случаях достигаются путем обхода ассоциаций.Иногда при создании нового объекта нецелесообразно передавать все необходимое в конструктор, так что это один из случаев, когда вам может понадобиться какой-то доступ к данным внутри самой доменной модели.Обычно люди передают в службу данных через интерфейс, так что модель домена может быть обеспечена доступом к данным, но остается отделенной от реализации уровня данных.Но по большей части доменные объекты действуют и взаимодействуют с другими объектами домена, которые уже созданы.

...