2010-04-14 2 views
10

우리 모두가 알고있는 M-V-VM의 요점은 걱정에 관한 것입니다. MVVM, MVC 또는 MVP와 같은 패턴에서 주된 목적은 데이터에서보기를 분리하여보다 유연한 구성 요소를 구축하는 것입니다. 먼저 많은 WPF 응용 프로그램에서 볼 수있는 매우 일반적인 시나리오를 시연하고 내 요점을 만들 것입니다 :M-V-VM은보기로 누출되는 모델이 아닙니까?

따옴표 묶음을 묶어서 화면에 표시하는 StockQuote 응용 프로그램이 있다고 가정 해보십시오. 일반적으로이있을 것 :

StockQuote.cs을 : (모델)

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

StockQuoteViewModel.cs : (뷰 모델)

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가 모델로 간주되며 ViewModel의 ObservableCollection을 통해 뷰에 노출됩니다. 기본적으로, 뷰는 모델에 대한 지식을 가지고 있음을 의미합니다. 그것은 M-V-VM의 전체 패러다임을 위반하지 않습니까? 아니면 내가 여기서 뭔가를 놓치고 ....?

답변

3

아니요. StockQuote는 노출되지 않습니다. 보기에 (느슨하게 입력 된) 인터페이스 만 지정하고 있습니다. 보기에는 기호 및 가격의 두 가지 속성 만 있습니다. StockQuote를 구현하는 한 StockQuote를 다른 것으로 쉽게 대체 할 수 있습니다.

+0

WPF 데이터 바인딩의 '느슨한'특성에 의존하기는하지만 좋은 지적입니다. 그러나 StockQuote 컬렉션을 사용하는 VM에 대한 단위 테스트를 작성한 경우 StockQuote 클래스를 변경하면 중단됩니다. –

8

저는 MVVM보다 MVC에 익숙하지만 일반적으로보기에 모델에 대한 지식이있는 것으로 받아 들여지고 있습니다. Model이 View에 대한 지식이 없으면 괜찮습니다.

실제로 어떤 이유로 든 문제가되는 경우보기가 제공되는 원시 데이터 이외의 것을 아무것도 인식하지 않는 "수동보기"디자인을 확인하십시오.

+5

정확히 입력 할 내용입니다. 뷰는 모델에 대해 * 뭔가 *를 알아야합니다. 그렇지 않으면 뷰는 무엇입니까? – timdev

7

MVVM에서보기 모델은보기에서 쉽게 처리 할 수있는 방식으로 모델의 데이터를 노출하는보기와 모델 사이의 어떤 것입니다. 엄격한 MVVM 애플리케이션에서 뷰는 뷰 모델에 대해서만 모델에 대해 알지 못합니다. 뷰 모델은 뷰에 의해 취급이 용이 특정 UI를 수집하여 많은 주식 시세를 노출하기 때문에 (당신의 구체적인 예에서

뷰 모델은 StockQuoteViewModel 호출 할 수 없습니다하지만 StockQuotesViewModel는 (복수의 인식) ObservableCollection<T>을하기 때문에 INotifyCollectionChanged<T> 구현). 컬렉션의 항목 유형은 단일 StockQuote 개체의 데이터를 노출하는보기 모델 (예 : StockQuoteViewModel)이어야합니다. 이러한 뷰 모델에서는 $ -symbol을 Price에 추가하는 등의 논리를 추가 할 수 있습니다.

보기 모델에서 일부 모델 개체를 노출하는 것이 더 쉽지만 올바른 방법은 각 모델 클래스에 대한보기 모델을 만드는 것입니다.

최고 감사합니다,

0


올리버 Hanappi는 어쩌면 나는이 잘못을 가지고 있지만 완전히 모델을 캡슐화하는 뷰 모델의 생각이 아니다. 예를 들어 주식 시세가 뷰에 노출되어 있지만 바인딩 할 뷰 모델의 네이티브 속성에 매핑해야합니다.이는 데이터를 모델/뷰로 전송하는 동안 필요할 수있는 "클리닝"을 필요로합니다.

그런 식으로보기는보기 모델 만 알고 있습니다. 또한 모델이 레거시가 아니면 인터페이스로 구현되어 뷰 모델 간의 결합을 더욱 줄일 수 있음을 의미합니다.

1

필자는 ViewModels가 Properties to Fields이기 때문에 모델에 대한 이해를합니다. 이는 매우 불분명 한 비유이지만 뷰가 모델에 직접 액세스하는 경우 적절히 격리되지 않았다는 것을 의미합니다. 비공개 필드를 래핑하는 클래스의 사소한 속성처럼 View에서 소비 할 수 있도록 관련 Model 속성을 ViewModel 속성에 래핑 할 때 많은 복제 및 상용구 코드가 필요합니다. 이것은이 패턴으로 저를 괴롭히는 것이고, 그 혜택이 부 풀릴만한 가치가 있는지에 대해서는 아직 결정되지 않았습니다.

이 예제에서는 개별 StockQuote를 나타내는 View에 대해 중요한 논리를 수행하지 않으므로 각 StockQuote 인스턴스에 대해 VM을 작성하는 것이 과도하다고 생각합니다. 이 작은 경우에는 Model 클래스에 직접 바인딩하는 것이 훨씬 깔끔하고 유지 관리가 쉽다고 생각합니다. 작은 케이스를위한 VM을 생성하면 커플 링이 줄어들지 만 복잡성이 증가 할 것이며 이것이 유익한 지 여부에 대한 사례 별 판단의 호출이라고 생각합니다.

관련 문제