0

Много статей разных перечитал, никак не могу понять что должно находиться в Model, а что во ViewModel. Вроде бы я так понял что в Model одни поля и свойства, а во ViewModel одни методы. Но какой пример не посмотрю Model вообще чаще всего не указывается такой класс, одна ViewModel везде и в ней и свойства и методы. Подскажите какой нибудь правильный пример MVVM приложения пожалуйста.

P.S. Еще в некоторых примерах (особенно на MSDN) видел кучу всякого наследования, базовые модели и вьюмодели, интерфейсы какие то... Это реально надо? Очень сложно для восприятия это все конечно... :(

Developer
  • 1,756
  • 1
    Вам сюда и сюда. Базовая VM нужна, чтобы не дублировать реализацию INPC. А базовая модель не нужна никому. – VladD Apr 17 '16 at 12:35
  • @VladD а вот если я пишу WCF сервис то что где должно быть? Контракт сервиса это что? ViewModel? А что тогда Model? Контракты данных? Или контракты вообще не относятся к MVVM и должны в проекте идти особняком? – Developer Apr 17 '16 at 13:11
  • 1
    Модель, конечно. Чистейшая, образцовая модель. Всё, что не относится к бизнес-логике и отображению — модель. – VladD Apr 17 '16 at 13:17
  • @VladD контракт данных модель? Или контракт сервиса? А ViewModel будет контракт сервиса? – Developer Apr 17 '16 at 13:30
  • Вид отвечает за внешний вид. ViewModel отвечает за визуальные данные "что отображать" (не путать с "как отображать" у вида) и заодно является получателем событий с вида. А модель является сосредоточием бизнес-логики. Так что задача вьюмодели предоставлять данные для отображения (возможно в нужном виде - есть и такой тренд) и реагировать на команды управления с вида, которые касаются логики данных для визуализации либо модели – vitidev Apr 17 '16 at 13:37
  • @DarkByte: Всё, относящееся к WCF — модель. – VladD Apr 17 '16 at 14:04
  • @VladD что??? Контракт сервиса вы предлагаете моделью сделать??? Мне кажется это несколько странным... Во первых в контракте сервиса больше функций чем данных, а в модели обычно больше данных как я понял, хотя и функции тоже бывают (или нет?). Во вторых у меня данные сервиса будут биндиться к представлению, а это значит что он никак не может быть моделью, ведь представление не должно вообще знать о модели. – Developer Apr 17 '16 at 14:06
  • @DarkByte: Это всё не важно. Количество данных или функций не играет вообще никакой роли, модель — это модель. А вот биндиться к модели нельзя, да. Например, потому, что модель, особенно типа WCF, не может бежать в UI-потоке, она ж медленная. Так что биндится придётся к VM. Вы всё же почитайте это. – VladD Apr 17 '16 at 14:17
  • @VladD так вот о том и речь !!! У меня же к контракту сервиса будет идти биндинг, значит он нефига не модель, а вьюмодель, а вы говорите что он тоже модель... Нестыковочка ! P.S. Я читал. – Developer Apr 17 '16 at 14:22
  • @DarkByte: Во-первых, давайте снизим градус эмоций и количество восклицательных знаков. Во-вторых, у вас не должен идти биндинг к WCF-классу, потому что он — модель, а не VM. Вы хотите упростить код, и биндится к классу, который по сути является моделью. Так не выйдет. – VladD Apr 17 '16 at 14:25
  • @VladD как вы представляете это себе? Вот у меня например в контракте сервиса есть коллекция подключенных клиентов (там тоже объекты другой ViewModel-и). Она обновляется исключительно из контракта сервиса. Но в полях этих объектов содержаться всякие там ip-адреса, и прочие параметры клиентов которые биндятся к View. Таким образом как вы предлагаете мне это сделать иначе? Я не знаю... – Developer Apr 17 '16 at 14:29
  • @VladD вы все таки ответьте пожалуйста, не молчите! Мне уже интересно стало какой же вы вариант решения этой проблемы предложите... Ибо я не представляю себе как иначе сделать, ведь обновлять список подключенных клиентов может только контракт сервиса, но и биндиться к этому списку мне надо! – Developer Apr 17 '16 at 15:02
  • Кстати как вы прокомментируете заявление Вадим-а? Вы меня запутали оба, один одно говорит, другой другое. :D – Developer Apr 17 '16 at 15:28
  • @DarkByte: Для начала, я бы сказал, что клиент — модельный объект. У вас может быть ClientVM к нему, если клиента нужно ещё и визуализировать. А может и не быть. Кто к кому биндится, модель интересовать не должно, она вообще не знает о наличии UI в программе. – VladD Apr 17 '16 at 15:43
  • @VladD это и так понятно, я уже это и сказал, а что насчет остального? Особенно насчет списка клиентов. – Developer Apr 17 '16 at 15:50
  • @DarkByte: Если у вас параметры клиента доступны в UI, значит, вам параллельно к клиенту в модели нужна VM для клиента. ClientVM согласно логике программы собирает данные для клиента как части модели, обновляет модель, и запускает работать. – VladD Apr 17 '16 at 15:57
  • @DarkByte: Если вам нужен список для Binding'а, значит, у вас должен быть список VM, представляющих собой клиента. Но это не отменяет необходимость наличия и модельных объектов, представляющих собой клиента. При этом, например, список VM-клиентов практически обязан быть ObservableCollection<ClientVM>, а вот в каком виде у вас представлен список модельных клиентов, личное дело самой модели. – VladD Apr 17 '16 at 15:59
  • @VladD само собой ObservableCollection, это и так понятно, вопрос не в этом. Вопрос в том где именно эта коллекция будет располагаться если не в контракте сервиса? Только контракт сервиса может ее обновлять. – Developer Apr 17 '16 at 17:32
  • @DarkByte: Список Model.Client располагается в модели, и обновляется как ей (модели) угодно. ObservableCollection<ClientVM> располагается в VM, VM следит за моделью (так, как это позволяет модель) и обновляет коллекцию. – VladD Apr 17 '16 at 17:36
  • Что еще за Model.Client??? У меня нет такого списка... Как по вашему VM может обновлять ObservableCollection если обновлять его может только сервис? Откуда он данные возьмет? Сервис получает вызов функций при подключении / отключении клиентов и соответственно добавляет / удаляет их из коллекции, а как по вашему VM должен об этом узнать? – Developer Apr 17 '16 at 17:54

1 Answers1

1

Добрый вечер! View - это как везде и всегда интерфейс. Model - здесь так же стандартно, данные которые использует приложение. ViewModel - это прослойка которая при помощи механизма связывания (binding) связывает модель и и интерфейс. Здесь же реализуются методы манипулирования данными модели, а также бизнес-логика приложения. Вот не плохая статья на эту тему. http://professorweb.ru/my/WPF/documents_WPF/level36/36_5.php

  • написал много и ничего в тему по конкретному вопросу... И да этот пример я уже видел, вот как раз он один из самых сложных какие только я находил в интернете, мне бы что попроще... – Developer Apr 17 '16 at 12:31
  • ViewModel - это прослойка которая при помощи механизма связывания (binding) связывает модель и и интерфейс.

    Так биндинг же делается не во ViewModel, а во View. Биндинг описывается прямо в xaml-разметке. Причем тут вообще ViewModel?

    – Developer Apr 17 '16 at 12:34
  • И вообще со View мне все ясно - это чистая xaml разметка и ничего больше, я не понимаю чем отличаются Model и ViewModel !!! – Developer Apr 17 '16 at 12:34
  • 1
    Да биндинг делается в разметке, но связывается он с полями ViewModel, во ViewModel идет вся логика приложения, в Model как вы и описали только поля, да эти два класса можно слепить в один, но суть не в том чтобы писать как можно меньше кода, а писать читабильный понятный код. Поэтому идет разделения Model - только данные, ViewModel это часть от Model которая биндится к View компонентам, а так же методы которые могут использовать компоненты для изменения данных модели и остальная логика приложения. – Вадим Apr 17 '16 at 12:45
  • а вот если я пишу WCF сервис то что где должно быть? Контракт сервиса это что? ViewModel? А что тогда Model? Контракты данных? Или контракты вообще не относятся к MVVM и должны в проекте идти особняком? – Developer Apr 17 '16 at 12:48
  • Да если уж на то пошло и на WCF наложить паттерн MVVM тогда за Model можно взять DataContract (так как тут мы описываем какими данными мы манипулируем) а за ViewModel берем ServiceContract (тут мы реализуем нашу логику над нашими данными из модели), только если у нас тут не биндится View тогда это все дело больше похоже на простой Model-Controller. Но стоит ли тут применять данный паттерн решать только вам. – Вадим Apr 17 '16 at 13:23
  • то то и оно что у меня есть всякие там вещи, объявленные в контракте сервиса которые конкретно биндятся. Так как же будет правильнее сделать чтобы следовать канонам MVVM? – Developer Apr 17 '16 at 13:33
  • Тогда да как вы и написали выше, Model - DataContract - тут у нас только поля грубо говоря, описываем формат данных которых будет передавать сервис. ViewModel - это ServiceContract, здесь мы описываем модель данных для вида (ее собственно и биндим на вид) и все логику оставшуюся логику: как, куда, каким образом, сервис будет передавать нашу модель. – Вадим Apr 17 '16 at 13:49
  • скажите а в каком пространстве имен логичнее разместить интерфейс сервиса? Т.е. если сам сервис будет во ViewModels, то где его интерфейс? Там же? Но он же вроде не имеет отношения ко ViewModel... – Developer Apr 17 '16 at 14:03
  • Я имею ввиду интерфейс в плане не View, а interface. У каждого сервиса же должен быть базовый интерфейс, описывающий его функционал. – Developer Apr 17 '16 at 14:04
  • Да там же, вполне может быть (развели мы тут чат какой-то) – Вадим Apr 17 '16 at 14:07
  • не понял... ServiceContract это класс вы имеете ввиду? Или пространство имен? Если пространство имен то тогда уж ServiceContracts (с 's' на конце). Т.е. вы предлагаете сделать так: ServiceContracts.IService, ViewModels.Service? А не странновато их разносить так? Может тогда уж сделать так: ViewModels.ServiceContacts.IService, ViewModels.ServiceContacts.Service? – Developer Apr 17 '16 at 14:11
  • Я бы выделил такое дерево, Сервис: интерфейсы сервиса, модели, виды, модели видов. Чуть выше я вас не понял, но поправился. – Вадим Apr 17 '16 at 14:22
  • а вот VladD выше пишет что контракт сервиса это чистая модель, а не вьюмодель... И кого слушать? :D Запутали меня... – Developer Apr 17 '16 at 14:31
  • Пффф, чистая модель кроме описания данных ничего не должна иметь по определению, все операции (методы, функции) реализовывает ViewModel (или Controller), У меня все, спасибо за внимание ;) – Вадим Apr 17 '16 at 15:20