Руководство по структуре проекта многоуровневого приложения MVVM, DDD и WPF

17

Я пытаюсь настроить структуру своего приложения в VS, и я хочу "попробовать" и в будущем доказать это на разумном уровне. Это приложение будет переписано в WPF старого приложения Winform, которое не соблюдало никаких соглашений. Нет слоев, ярусов, сокращений и т. Д.

Это довольно простое корпоративное приложение. Я планировал использовать Linq To SQL, так как мои БД есть и, скорее всего, всегда будут MS SQL. Также у меня есть существующий набор навыков с ним.

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

Когда я слежу за MVVM, моя структура папок может выглядеть так:

Views
Models
ViewModels
Helpers

но как это вписывается в упрощенный многоуровневый подход DDD, где моя структура проекта может выглядеть следующим образом:

MyApp.UI
MyApp.Domain
MyApp.Data

Я положил Modelsв слой домена или у меня есть 3 версии скажем Person? Это приводит к другому вопросу о том, куда бы я поместил свой репозиторий и сопоставления объекта БД с объектом домена? Я бы предположил, что данные ...

ViewsЯ получил бы пойти в пользовательском интерфейсе, но ViewModelsтакже?

Наконец, где я буду встраивать свою бизнес-логику?

Я нашел следующее в CodePlex, DDD Example , и это помогло, но, похоже, для веб-приложения, хотя это может и не иметь значения, и мое незнание просвечивает.

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

Суть моего вопроса может быть показана следующим образом.
У меня есть tblPersonобъект, сгенерированный *.dbml. Это очевидно и будет принадлежать моему слою «данных».
Теперь я бы назвал Model, DTO, Domain Model или как там это называется в отдельном слое (проекте?) Person. Я потребуется Mapperдля Personна tblPersonчто я не уверен , куда девать.
Затем у меня будет ViewModel, скажем, EditPersonс собственными свойствами, из которых он извлекает, Personно, возможно, также и с другими.
Наконец, у меня будет View, связанный с этой ViewModel ....

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

Преломленный паладин
источник
Linq To SQL не подходит для больших проектов. Либо используйте Entity Framework, либо используйте другой ORM, например, nHibernate. Кроме того, это клиентское приложение или клиент-сервер?
Эйфорическая
Это клиентское приложение WPF. Кроме того, не могли бы вы объяснить, почему вы чувствуете, что L2S не подходит для приложений среднего или большего размера, когда мой единственный источник данных - MS SQL?
преломленный паладин

Ответы:

5

MVVM является шаблоном пользовательского интерфейса и используется в клиенте.

Части домена в DDD, которые используются в клиенте, вероятно, являются (частью) модели

View и ViewModel только для клиента.

Я поместил репозитории в (или рядом) с моделью, потому что они синхронизируют модель с серверной частью.

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

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

Чтобы уточнить часть о репозиториях и объяснить больше о позиционировании Business Logic

Если вы создаете систему, которая содержит отдельные клиентские и серверные / серверные репозитории, они могут использоваться на клиенте и на сервере. В клиенте для предоставления абстракции сервера (ов) и в сервере для предоставления абстракции других серверов и источников данных. Это просто шаблон.

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

Я действительно думаю, что DDD принадлежит на стороне сервера и «просачивается» к клиенту.

Эрно
источник
2

У вас есть верное направление в выборе шаблона проектирования MVVM для приложения WPF.

Do I put the Models in the Domain layer?

Да, ваши модели могут быть размещены в домене

Where would I put my Repository and mappings of DB Object to Domain Object?

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

ViewModels also?

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

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

Изменить: ссылка была добавлена ​​выше, и спасибо за @Den!

Юсубы
источник
пожалуйста, прокомментируйте при голосовании.
Юсубов
1
Фанаты DDD хотят использовать это везде. Ссылка по теме: stackoverflow.com/questions/810606/is-ddd-a-waste-of-time
День
@Den, спасибо за ссылку! я планировал поискать это.
Юсубов
1

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

Торговая точка MVVM - это связь между представлением и моделью представления. Целью здесь является устранение логики в представлении.
Как и представление, модель должна быть достаточно легкой и использоваться только для доступа к информации (данным), необходимой для работы модели представления. Модель может смешивать доступ к различным источникам данных, но не должна иметь бизнес-логики. В большинстве случаев у вас есть одно хранилище данных, чтобы поразить. В некоторых случаях вы этого не делаете. Когда вы этого не сделаете, уместно использовать Модель, чтобы скрыть источник данных от ВМ.

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

Я бы выложил свой проект так:

 project.Views
 project.ViewModel
 project.Model
 project.DataStructs

и этот слой может быть добавлен по мере необходимости:

 project.Helpers

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

Отказ от ответственности: я не эксперт DDD, но я понимаю общую суть и вижу ценность в подходе.

Ваш домен будет проблемой, которую вы рассматриваете.
В модели домена собирается соответствовать в первую очередь к ViewModels , которые вы создаете; немного в пределах Представлений; и небольшой кусок в Model / DataStructs.

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

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

На ваши вопросы:

  1. Не пытайтесь накладывать DDD на MVVM. Это просто не сработает. DDD - это не шаблон макета, это подход к рассмотрению вашей общей проблемы.
  2. Репозиторий и сопоставления будут жить либо в project.Data, либо в project.Model в зависимости от ситуации.
  3. Не используйте слой с именем UI, если только это не то, что вы хотите назвать project.Views.
  4. Бизнес-логика перейдет в View-Model.

источник
1
Хорошо, некоторые, возможно, невежественны, следите за вопросами. (1) вы бы сделали каждый из них отдельным проектом или просто папками (например, Project.View и т. Д.)? (2) DataStructs - это место, куда вы поместите * .dbml или Project.Data? (3) Так что, по вашему мнению, у меня не было бы Project.Domain? Я видел, что использовал несколько раз, поэтому я спрашиваю.
преломленный паладин
@RefractedPaladin - 1) просто папки в проекте. Вы можете привести аргумент, что Data должен быть собственным проектом. С точки зрения технического обслуживания, любой способ эквивалентен. 2) да, именно так 3) нет, у меня не было бы папки .Domain. ИМО, наша работа - сопоставить приложение с областью проблем бизнеса. Таким образом, Домен пронизывает все слои проекта.