Доменно-ориентированный дизайн - как должны быть организованы слои?

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

Мне интересно узнать о подходе к проектированию, основанному на домене, и я столкнулся с некоторыми проблемами, чтобы познакомиться с ним (конечно же, на начальном уровне).
Вот это -

Я хочу создать приложение для сохранения данных о людях в базе данных и отображения сведений о людях в WPF DataGrid (я знаю, что DDD определенно не для приложений такого масштаба, а просто для упрощения работы такого любителя, как я). Итак, я создал доменный класс «Человек», что-то вроде -

    public class Person
    {
        public Person(dataType paramA)
        {
            this.PropertyA = paramA;
        }

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

        public dataType PropertyX
        {        
            //some code that manipulates private field    
        }

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

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

Примечание:

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

  2. Это приложение WPF, но не обязательно в шаблоне MVVM, и я намеренно хочу использовать код, стоящий за ним.

Мои вопросы -

  1. Какие коды принадлежат Application Layer?

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

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

  4. Если код программной части обращается к Application Layer, тогда должен ли Application Layer разговаривать с Data Repository? Но что, если требуется какой-то доступ к домену, который не связан с доступом к данным (может быть, не в этом приложении, но это может произойти, верно?) В этом сценарии, кто этот X парень (суб- слой / модуль) в Domain Layer, с которым должен разговаривать Application Layer?

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

РЕДАКТИРОВАТЬ: Я не уверен, что в Data Repository должна быть ссылка Domain Model.


comment
Служба приложений может возвращать объект домена [Реализация DDD, стр. 522], но не должна его использовать (клиент должен вызывать метод службы приложения для изменения объекта, но не должен изменять его напрямую).   -  person Muflix    schedule 11.08.2019
comment
Аналогичную иллюстрацию слоев можно найти здесь dddsample.sourceforge.net/architecture.html   -  person Muflix    schedule 11.08.2019


Ответы (1)


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

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

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

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

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

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

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

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

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

РЕДАКТИРОВАТЬ

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

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

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

person Sisyphus    schedule 05.05.2011
comment
@Sisyphus: +1 пока что за чистое и подробное описание и, конечно, за ваше время, чтобы просветить меня. Но у вас будут еще вопросы :) - person atiyar; 06.05.2011
comment
@Sisyphus: Еще раз спасибо. Ваше предложение было аккуратным, и пример разницы между службами приложений и доменными службами был очень полезен. Еще один вопрос. Должен ли уровень приложения когда-либо иметь прямой доступ к репозиторию или он всегда проходит через уровень домена? Я имею в виду, что почти всегда каждый запрос выполнение выполняет какие-то проверки ограничений домена (может быть проверка) в отношении любого запроса отправки, верно? Тогда не должен ли уровень приложения отправлять каждый запрос на уровень домена, и только уровень домена имеет доступ к репозиторию? - person atiyar; 08.05.2011
comment
Поскольку количество комментариев ограничено, я добавил к своему ответу. См. Раздел РЕДАКТИРОВАНИЕ. - person Sisyphus; 08.05.2011
comment
@Sisyphus: Мои концепции полностью согласны с вашей точкой зрения о модели домена, но я спрашивал, должен ли уровень приложения вызывать какую-то службу доступа к данным или службу проверки достоверности на уровне домена, а НЕ в модели домена , который, в свою очередь, проверяет ограничения домена, а затем либо вызывает репозиторий, либо отклоняет запрос. Допустим, имя человека должно содержать не менее 6 символов. Какой уровень отвечает за выполнение таких проверок ограничений домена, когда уровень приложения пытается сохранить данные Person в базе данных? - person atiyar; 09.05.2011
comment
В этом примере у меня было бы правило в объекте Person. Хотя никто не ответил. Всегда старайтесь поддерживать объекты в допустимом состоянии. Куда девать логику можно по разному. Тема больших дискуссий - проверка Google в DDD для просмотра мнений / примеров. В общем, правильное присвоение значения по сравнению с сущностью, отказ от установщиков, использование шаблонов, таких как Factory, для создания объектов и Specification для проверки сложных условий - ценные методы, которые могут сделать это менее проблематичным. Эти методы могут устранить многие основные проблемы. Но относительно того, как обрабатывать сложные случаи валидации, нет однозначного ответа. - person Sisyphus; 09.05.2011
comment
Еще раз большое спасибо за ваше время. До скорого... :) - person atiyar; 09.05.2011
comment
Заключительный комментарий. Пока не вдавайтесь в технические подробности. Выполнить DDD строго по инструкции сложно, требуется опыт, чтобы действительно даже попытаться. Первый проект DDD, над которым я работал, был до того, как идея стала популярной. У нас был Эванс, ограниченный опыт и мало других рекомендаций. Мы не делали различий между объектами-значениями и сущностями, агрегаты признавались концепциями в дизайне, но не применялись в коде. Сторонники DDD назвали бы это чушью, но мы написали хороший код, и приложение пошло на пользу. По мере накопления опыта вы можете совершенствовать свою технику. - person Sisyphus; 09.05.2011
comment
Я буду иметь это в виду, особенно когда объекты даже используются вокруг Naked (на самом деле, я не знал, что объекты домена можно использовать таким образом и по-прежнему называться объектами домена) ... еще раз спасибо за ваше время и предложения и поделиться ценными мыслями :-) - person atiyar; 09.05.2011