У меня есть приложение WPF, где я хочу применить MVVM для уровня представления и DDD для всего приложения. Я очень смущен тем, как я должен применять архитектуру. Можете ли вы дать мне несколько советов, поскольку мне кажется, что я полностью перепутал на данный момент со следующей попыткой дизайна:
У меня есть 4 слоя:
-
Presentation Layer
: здесь находится мое клиентское приложение WPF. -
Application Layer
. Здесь у меня есть мои службы, которые предполагают связь с услугами домена для бизнес-правил и CRUD. Он работает просто как слой с антикоррупцией между слоямиPresentation
иDomain
. -
Domain Layer
. Здесь у меня есть свои агрегированные объекты, объекты домена и некоторые службы, которые раскрывают бизнес-правила, такие какIsTooOld(Person person)
-
Infrastructure Layer
. Это самый низкий уровень, здесь находится инфраструктура,IRepository
,IEntity
и т.д.
Позвольте создать простой сценарий с этими слоями на основе DDD: иметь объект Person в базе данных, отобразить его, CRUD в базе данных, проверить день рождения людей и показать его пользователю.
Уровень презентации
Я начну с части WPF. Я создаю следующие классы:
-
PersonView
: вид XAML человека -
PersonViewModel
:ViewModel
, который предоставляет функции дляPersonView
.PersonView
связывается с этим, и этотViewModel
предоставляет значения изPersonModel
-
PersonModel
. Это MVVM-модель, с которой мояPersonViewModel
тесно связана с.
Уровень домена
Это достаточно хорошо для уровня представления. Теперь я хочу подключиться к базе данных, чтобы получить объект person, чтобы представить его.
Я должен создать:
-
PersonEntity
вDomain Layer
: агрегат для объекта базы данных, используемый для сопоставлений с базой данных. Он находится в слоеDomain
. -
Person
вDomain Layer
: Это модель домена DDD. Я приведу здесь немного логики, и я не хочу отправлять объекты объектов, как предлагает DDD.
Уровень приложения
Хорошо, у меня уже есть модели на 3 человека, которые очень похожи друг на друга. Как насчет еще нескольких возможностей для доступа к данным и сервисов?
-
PersonService
вApplication Layer
: когда мой уровень представления хочет взаимодействовать с этим слоем, ему необходимо преобразовать егоPersonModel
(модель MVVM) вPerson
(модель домена). Затем эта служба на прикладном уровне преобразуетPerson
(модель домена) вPersonEntity
(объект объекта) и выполняет CRUD с базой данных. Эта служба использует еще одинPersonService
(см. Ниже) на уровне домена для проверки/применения некоторых бизнес-правил. -
PersonService
вDomain Layer
: этот уровень работает только с объектом доменаPerson
. Он имеет правила, связанные с бизнесом, такие какbool IsTooOld(Person person)
.
Подводя итог, я получил 7 классов для простого сценария:
-
Presentation.WpfClient.View.PersonView
-
Presentation.WpfClient.ViewModel.PersonViewModel
-
Presentation.WpfClient.Model.PersonModel
-
Application.ApplicationServices.PersonService
-
Domain.Application.Services.PersonService
-
Domain.Application.Models.Person
-
Domain.Application.DbEntities.PersonEntity
(причина, по которой я создал это, заключается в том, что я не могу использовать сопоставление для сложных объектов домена, поэтому я просто помещаю здесь аннотации данных вместо отображения объектов домена)
Это очень неудобно. Я не уверен, как мне переструктурировать его и принести пользу как дизайну, управляемому доменом, так и шаблонам MVVM. Я действительно застрял, и я действительно с нетерпением жду любых советов или примеров реальной жизни для применения как MVVM, так и проекта, управляемого доменом. Я также открыт для любой обратной связи для соглашений об именах или стратегий для минимизации этой большой работы для простых операций.
У меня все еще есть два конкретных вопроса:
-
Следует ли удалять модели из уровня представления (модели MVVM) и использовать только модели из уровня домена (модели DDD)? Разве это не нарушение MVVM в этот момент?
-
Должен ли я объединять модели сущности (базы данных) с моделями доменов? Разве это не нарушение DDD?
Обновление
Решения, принятые мной:
- Использование модели домена для модели MVVM (удалено
PersonModel
) - Используйте внешние сопоставления для той же модели для базы данных (удалено
PersonEntity
добавлено PersonMappings). Использование модели persistence намного дороже, чем просто ее отображение. См. http://enterprisecraftsmanship.com/2016/04/05/having-the-domain-model-separate-from-the-persistence-model/ из ответа Владимира.
Наконец, это выглядит так:
-
Presentation.WpfClient.View.PersonView
-
Presentation.WpfClient.ViewModel.PersonViewModel
-
Application.ApplicationServices.PersonService
(crud с некоторой логикой, связанной с приложением) -
Application.ApplicationServices.Mappings
(Здесь есть абстракции и отображения репозитория) -
Domain.Application.People.Person
(объект объекта в нем ограниченный контекст, объект достаточно умен, чтобы обрабатывать логику домена).