MVVM Разъяснение

15

Мы собираемся написать наше первое приложение WPF и знакомимся с шаблоном MVVM. Мы создали много приложений Winform и имеем архитектуру, которая была очень успешной для нас. У нас возникли небольшие проблемы с переводом этой архитектуры или определением того, как определенные части нашей архитектуры соответствуют модели MVVM.

Исторически у нас есть Gui (основной exe), который затем связывается с dll BusinessLogic. BusinessLogic связывается с dll-библиотекой DAL через веб-сервис, а DAL взаимодействует с БД. DAL, BusinessLogic и GUI ссылаются на одну и ту же BusinessObjects dll.

Архитектура AsIs

Часть перехода на MVVM довольно проста. Наш графический интерфейс по-прежнему будет содержать представления, наши BusinessOjbects будут по-прежнему содержать модель, а наш DAL будет по-прежнему взаимодействовать с БД (хотя технология их реализации может измениться).

В чем мы не уверены, так это в нашем компоненте BusinessLogic. Исторически это обеспечивало бы функции для вызова графического интерфейса, чтобы затем заполнять элементы управления в представлениях (т. Е. GetCustomerList, который возвращал бы список объектов Customer или типичных функций CRUD).

Основное препятствие, которое у нас есть, заключается в том, будет ли шаблон MVVM вызывать дополнительный компонент для размещения ViewModels или если мы просто изменим наше мышление и перенесем то, что мы использовали в качестве нашего компонента BusinessLogic, на ViewModels?

Представляет ли наш компонент BusinessLogic ViewModels?

user7676
источник
Это немного похоже на решение проблемы. Есть ли веская причина, по которой вы переходите на MVVM? Я фанат шаблона, но ваше предыдущее решение не работает? Модель представления похожа на наблюдателя. Он содержит логику представления и данные поверхностей через привязку данных. Он должен знать о вашей бизнес-логике и иметь возможность обращаться к этому уровню, но я бы не свернул бизнес-логику с самой моделью представления.
Джереми Ликнесс

Ответы:

19

В общем, я бы не стал размещать бизнес-логику на уровне модели представления. Но термин «бизнес-логика» вводит в заблуждение.

Эрик Эванс использует модель, в которой бизнес-логика делится на две категории

  • Доменная логика - логика, относящаяся к фактической проблемной области, которую вы решаете
  • Логика приложения - логика, связанная с тем, что вы создаете приложение

Он упоминает пример бухгалтерского приложения. Правила об учетных записях, сообщениях, налоговых счетах и ​​т. Д. Являются правилами домена, правилами, относящимися к области бухгалтерского учета. Логика импорта / экспорта CSV не имеет никакого отношения к области бухгалтерского учета. Эти правила существуют исключительно потому, что мы создаем программное приложение. Это примеры логики приложения.

Правила домена НИКОГДА не должны входить в слой модели представления. Если вы следуете шаблону MVVM, то доменные правила, без сомнения, переходят на уровень модели.

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

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

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

Пит
источник
1
Отличный ответ. Мне нравится, когда ViewModel содержит только логику представления. Можете ли вы добавить ссылку, связанную с вашей точкой Эрика Эванса?
user7676
Я сомневаюсь, что смогу найти ссылку, потому что, по-моему, я получил ее из его книги «Управление через домен». Во всяком случае, я думаю, что это отличный пример различия между логикой домена и приложения. Подробнее о книге можно прочитать
Пит
5

Да.

Уровень бизнес-логики представлен уровнем VM. Так что просто перенесите свою ментальную модель.

Чтобы помочь с миграцией вашей ментальной модели, есть один небольшой нюанс: объекты GUI (представление) должны быть связаны с объектами на уровне VM. Это связывание переводится на | подразумевает, что представление больше не является слоем, который «выполняет вызов» для извлечения чего-либо еще. Призыв к извлечению данных будет исходить от виртуальной машины.

Чтобы лучше объяснить: Да, объект в представлении должен будет измениться, чтобы вызвать последовательность действий, которые будут выполнять вызов. Но View не делает сам вызов. И в этом случае я считаю, что нажатие кнопки эквивалентно чему-то измененному в представлении, но все равно не выполняет вызов.

В первом случае этот объект View будет связан с объектом VM. ВМ должна прослушивать событие изменения свойства в связанном объекте. Затем событие изменения объекта может быть связано с функцией VM для вызова модели.

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

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

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


источник
Спасибо за подтверждение. Мы понимаем нюанс взаимодействия View с ViewModel и будем придерживаться модели привязки и отбрасывать «вызов».
user7676
Я заметил, что этот ответ потерял голос. Мне было бы интересно, если бы downvoter прокомментировал почему? Или, возможно, добавить свой собственный ответ, если они не разделяют эту точку зрения.
user7676
1
Я согласен с тем, что уровень бизнес-логики представлен уровнем виртуальных машин, однако я думаю, что части вашего ответа могут сбивать с толку. ViewСлой предназначается , чтобы быть визуальным представлением ViewModel или модели, так что вместо того , чтобы сказать событие щелчка подключено к вызову функции на виртуальной машине, лучше определение было бы сказать команду в VM визуализируются в виде кнопки Просмотр слоя. Кроме того, мне, как правило, не нравится, когда мой уровень модели может напрямую обращаться к DAL, поэтому мой поток приложений обычно идет туда VM -> DAL -> DB, где и то, VMи DALдругое используют простые Modelобъекты данных.
Рэйчел
4
Я не согласен с этим ответом. ViewModel - это модель представления, она содержит логику представления, а не бизнес-логику. ViewModels являются частью уровня представления
simoraman
1
@simoraman - шаблон MVPVM соответствует тому, что вы предлагаете. Я думаю, что MVPVM - хороший шаблон, но немного тяжелый для небольших приложений. Я действительно призываю вас выразить свои мысли и внести свой вклад в этот вопрос.
5

Вы правы в том, что вы по сути замените свою BusinessLogic dll своим слоем ViewModel, однако я думаю, что самое большое отличие, с которым вы столкнетесь, заключается в том, как слой View / UI взаимодействует с вашим слоем ViewModel / BusinessLogic.

В WinForms GUI является вашим приложением и отвечает за поток приложений. В WPF / MVVM ваши ViewModels - это ваше приложение, а графический интерфейс пользователя становится просто удобным интерфейсом для взаимодействия с ViewModels.

Например, в WinForms у вас могут быть DataGrid и Button, а когда вы нажимаете эту кнопку, вы вызываете BusinessLogicLayer.GetProducts() и загружаете полученные объекты Product в DataGrid.

С WPF у вас будет ViewModel, который содержит ObservableCollection<Products>иICommand GetProducts , и выполнение команды вызывает DAL и загружает коллекцию продуктов. Но чтобы обеспечить удобный интерфейс для этого, вы должны создать View, который отображает вашу ViewModel, используя DataGrid для коллекции Products, и кнопку для команды GetProducts.

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

Рейчел
источник
1
Я согласен с GlenH7, это хороший ответ для тех, кто начинает с WPF. Мы получаем сдвиг парадигмы взаимодействия между View и ViewModel, так что это не совсем соответствует теме, которую я задал.
user7676