M-V-VM, Разве Модель не просачивается в Представление?

Точка M-V-VM, как все мы знаем, о speraration проблем. В шаблонах как MVVM, MVC или MVP, основная цель состоит в том, чтобы отделить Представление от Данных, таким образом, создающих более гибкие компоненты. Я продемонстрирую сначала очень общий сценарий, найденный во многих приложениях WPF, и затем я выскажу свое мнение:

Скажите, что у нас есть некоторое приложение StockQuote, которое передает набор потоком кавычек и отображает их на экране. Как правило, у Вас было бы это:

StockQuote.cs: (Модель)

    public class StockQuote
    {
       public string Symbol { get; set; }
       public double Price { get; set; }
    }

StockQuoteViewModel.cs: (ViewModel)

   public class StockQuoteViewModel
   {
      private ObservableCollection<StockQuote> _quotes = new ObservableCollection<StockQuote>();

      public ObservableCollection<StockQuote> Quotes 
      {
         get
         {
            return _quotes;
         }
      }
   }

StockQuoteView.xaml (Представление)

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="Window1" Height="300" Width="300">
    <Window.DataContext>
        <local:StockQuoteViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <DataTemplate x:Key="listBoxDateTemplate">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Symbol}"/>
                <TextBlock Text="{Binding Price}"/>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ListBox ItemTemplate="{StaticResource listBoxDateTemplate}" ItemsSource="{Binding Quotes}"/>
    </Grid>
</Window>

И затем у Вас был бы некоторый сервис, который подаст ObservableCollection с новым StockQuotes.

Мой вопрос - это: В этом типе сценария StockQuote считают Моделью, и мы подвергаем это Представлению через ObservableCollection ViewModel. Который в основном означает, наше Представление имеет знание Модели. Разве это не нарушает целую парадигму M-V-VM? Или я пропускаю что-то здесь....?

10
задан BFree 14 April 2010 в 22:13
поделиться

6 ответов

Нет. Вы не выставляете StockQuote. Вы только указываете (слабо типизированный) интерфейс в представлении. Представлению известно только два свойства: символ и цена. Вы можете легко заменить StockQuote на что-нибудь еще, если оно их реализует.

3
ответ дан 3 December 2019 в 17:57
поделиться

Я больше знаком с MVC чем MVVM, но общепринято, что представление будет знать модель. Пока Модель не знает View, это нормально.

Если по какой-то причине это действительно вызывает беспокойство, обратите внимание на схему «Пассивное представление», где представление не знает ничего, кроме передаваемых ему необработанных данных.

8
ответ дан 3 December 2019 в 17:57
поделиться

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

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

1
ответ дан 3 December 2019 в 17:57
поделиться

Возможно, я ошибаюсь, но идея модели представления не заключается в полной инкапсуляции модели. Например, у вас есть котировки акций, представленные в представлении, но они должны быть сопоставлены со свойствами, присущими модели представления, которые затем будут привязаны к. Это необходимо для «очистки», которая может потребоваться во время передачи данных в модель / представление.

Таким образом, представление всегда знает только модель представления. Это также означает, что если бы модель не была унаследованной, ее можно было бы реализовать как интерфейс и еще больше уменьшить связь между моделями представления.

0
ответ дан 3 December 2019 в 17:57
поделиться

Посмотрите видео: Джейсон Долинджер на MVVM . Он ответит на ваш вопрос.

Также см. Вопрос SO wpf mvvm confusion для получения дополнительных ресурсов.

3
ответ дан 3 December 2019 в 17:57
поделиться

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

В вашем конкретном примере модель представления не должна называться StockQuoteViewModel , но StockQuotesViewModel (помните о множественном числе), потому что модель представления раскрывает многие котировки акций определенной коллекцией пользовательского интерфейса. который легко обрабатывается представлением (поскольку ObservableCollection реализует INotifyCollectionChanged ). Тип элементов в коллекции должен быть моделью представления (например, StockQuoteViewModel ), которая предоставляет данные из одного объекта StockQuote. В такой модели представления вы можете добавить логику, такую ​​как добавление символа $ к Price и так далее.

Часто проще представить некоторые объекты модели в модели представления, но правильным способом было бы создать модель представления для каждого класса модели.

С уважением,
Оливер Ханаппи

7
ответ дан 3 December 2019 в 17:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: