MVVM의 기본 개념-ViewModel은 무엇을해야합니까?


83

MVVM의 개념을 이해하기 위해 이미 여러 블로그를 읽고 몇 가지 프로젝트를 살펴 보았습니다.

내가 이해하는 바에 따르면 는 멍청한 것이며 전달되는 것을 제시하는 방법을 알고 있습니다.

모델 은 단순한 데이터 일 뿐이며 ViewModel 은 둘 사이의 패딩처럼 작동하는 것으로, Model 에서 정보를 가져 와서 View로 전달 해야 하며, View 는이를 표시하는 방법을 알아야합니다. 또는 반대로 View 의 정보가 변경되면 변경 사항을 Model 에 전달해야합니다 .

그러나 나는 여전히 개념을 적용하는 방법을 모릅니다. 누군가 내가 개념을 이해할 수 있도록 아주 간단한 시나리오를 설명 할 수 있습니까? 이미 여러 프로젝트를 살펴 봤지만 여전히 완전히 이해가되지는 않습니다. 그래서 누군가가 평범한 영어로 쓸 수 있다면 좋을 것입니다.


2
"전달되는 것을 제시하는 방법을 알고있다"는 견해에 동의 할 수 없다. View는 VM에서 데이터를 가져옵니다. 아무도 데이터를 전달하지 않습니다. 아무도보기에 대해 모릅니다. 이것은 MVP와의 중요한 차이점입니다. MVP에서 (u는 코드 숨김 논리가있는 간단한 WPF 응용 프로그램에 대해 생각할 수 있습니다. MVP 패턴입니다.) 코드 숨김은 말한대로 데이터를 View에 전달하는 발표자입니다.
Grigory

답변:


146

나는 이것을 이렇게 생각하고 싶다.

당신이 말했듯이 조회수는 멍청합니다. MVVM에 대한 관련 MSDN 기사의 저자 인 Josh Smith 는 뷰가 "데이터가 입는 옷"이라고 말했습니다. 뷰는 실제로 데이터를 포함하거나 직접 조작하지 않으며 뷰 모델의 속성 및 명령에 바인딩됩니다.

모델은 비즈니스 개체에서와 같이 애플리케이션의 도메인 을 모델링 하는 개체입니다. 애플리케이션이 뮤직 스토어입니까? 아마도 모델 개체는 아티스트, 앨범 및 노래 일 것입니다. 애플리케이션이 조직도 브라우저입니까? 아마도 모델 개체는 관리자와 직원이 될 것입니다. 이러한 모델 개체는 어떤 종류의 시각적 렌더링과도 관련이 없으며, 적용하는 응용 프로그램과도 직접 관련이 없습니다. 모델 개체는 어떤 종류를 나타내는 개체군으로서 자체적으로 완전히 이해되어야합니다. 도메인의. 모델 계층에는 일반적으로 서비스 접근 자와 같은 것이 포함됩니다.

이것은 우리를 Viewmodels로 가져옵니다. 그들은 무엇인가? GUI 애플리케이션 을 모델링 하는 객체입니다.즉, 뷰에서 사용할 데이터와 기능을 제공합니다. 빌드하는 실제 애플리케이션의 구조와 동작을 정의합니다. 모델 개체의 경우 도메인은 선택한 도메인 (음악 상점, 조직도 브라우저 등)이지만 뷰 모델의 경우 도메인은 그래픽 응용 프로그램입니다. 뷰 모델은 애플리케이션이 수행하는 모든 동작과 데이터를 캡슐화합니다. 그들은 객체와 목록을 속성으로뿐만 아니라 명령과 같은 것들로 노출 할 것입니다. 명령은 단순히 동작 (가장 간단하게 메서드 호출)을 전달하는 개체에 래핑 된 것입니다.이 아이디어는 시각적 컨트롤을 개체에 연결하는 데이터 바인딩에 의해 뷰가 구동되기 때문에 중요합니다. MVVM에서는 버튼에 Click 핸들러 메서드를 제공하지 않습니다.

저에게 가장 혼란스러운 부분은 다음과 같습니다.

  • 뷰 모델은 그래픽 응용 프로그램의 모델이지만 시각적 개념을 직접 참조하거나 사용하지 않습니다. 예를 들어, ViewModels에서 Windows 컨트롤에 대한 참조를 원하지 않습니다. 이러한 항목은 뷰에 표시됩니다. ViewModels는 단순히 데이터와 동작을 컨트롤 또는 바인딩 할 다른 개체에 노출합니다. 예를 들어-ListBox가있는 뷰가 있습니까? 당신의 viewmodel은 거의 확실하게 어떤 종류의 컬렉션을 가질 것입니다. 보기에 버튼이 있습니까? 당신의 뷰 모델은 거의 확실하게 몇 가지 명령을 가질 것입니다.
  • "뷰 모델"로 간주 될 수있는 몇 가지 종류의 개체가 있습니다. 이해하기 가장 간단한 종류의 뷰 모델은 "화면 XYZ에는 텍스트 상자, 목록 상자 및 세 개의 버튼이 있으므로 뷰 모델에는 문자열, 컬렉션, 그리고 세 개의 명령. " 뷰 모델 레이어에 맞는 또 다른 종류의 객체는 동작을 제공하고 뷰에서 더 유용하게 만드는 모델 객체를 감싸는 래퍼입니다. 여기에서 "두꺼운"뷰 모델 레이어와 "얇은"뷰 모델 레이어의 개념을 살펴볼 수 있습니다. "얇은"뷰 모델 계층은 모델 객체를 뷰에 직접 노출하는 뷰 모델 세트입니다. 즉, 뷰가 모델 객체의 속성에 직접 바인딩됩니다. 이것은 간단한 읽기 전용보기, 하지만 각 개체와 관련된 동작을 원하면 어떻게해야합니까? 모델은 애플리케이션과 관련이 없으며 도메인에만 관련되어 있기 때문에 모델에서 원하지 않습니다. 모델 개체를 래핑하고 바인딩 친화적 인 데이터 및 동작을 제공하는 개체에 넣을 수 있습니다. 이 래퍼 객체는 뷰 모델로도 간주되며, 뷰 모델 레이어가 "두꺼워 진"뷰 모델 레이어가됩니다. 뷰가 모델 클래스의 어떤 것에 직접 바인딩되지 않습니다. 컬렉션에는 모델 자체를 포함하는 대신 모델을 래핑하는 뷰 모델이 포함됩니다. 모델 개체를 래핑하고 바인딩 친화적 인 데이터와 동작을 제공하는 개체에 넣을 수 있습니다. 이 래퍼 객체는 뷰 모델로도 간주되며, 뷰 모델 레이어가 "두꺼워 진"뷰 모델 레이어가됩니다. 뷰가 모델 클래스의 어떤 것에 직접 바인딩되지 않습니다. 컬렉션에는 모델 자체를 포함하는 대신 모델을 래핑하는 뷰 모델이 포함됩니다. 모델 개체를 래핑하고 바인딩 친화적 인 데이터와 동작을 제공하는 개체에 넣을 수 있습니다. 이 래퍼 객체는 뷰 모델로도 간주되며, 뷰 모델 레이어가 "두꺼워 진"뷰 모델 레이어가됩니다. 뷰가 모델 클래스의 어떤 것에 직접 바인딩되지 않습니다. 컬렉션에는 모델 자체를 포함하는 대신 모델을 래핑하는 뷰 모델이 포함됩니다.

토끼 구멍은 더 깊어집니다. MVVM을 계속 작동시키는 ValueConverters와 같은 많은 관용구가 있으며, Blendability, 테스트 및 앱에서 데이터를 전달하는 방법에 대해 생각하기 시작할 때 적용 할 많은 관용구가 있습니다. 각 뷰 모델은 필요한 동작에 액세스 할 수 있지만 (여기에서 종속성 주입이 발생합니다) 위의 내용이 좋은 시작이되기를 바랍니다. 핵심은 비주얼, 도메인, 실제 애플리케이션의 구조와 동작을 세 가지 다른 것으로 생각하는 것입니다.


3
+1-일부 샘플 코드에서 발생한 "래퍼"ViewModel로 인해 혼란스러워서 여기에 왔습니다. :-) 나를 위해 그를 삭제 주셔서 감사합니다
Riegardt 스테인

1
좋은 대답-내가 +10을 할 수 있기를 바랍니다.
Nick Hodges

1
@nlawalker 매우 굉장합니다! 위의 이중 비트 u 코멘트는 오랫동안 저를 혼란스럽게 해왔습니다. 많은 기사와 블로그는 MVVM의 "주요 기능"에 대해서만 설명하지만, 사용하려고하면 상황이 매우 복잡해지기 시작합니다. ! "그보기를 탐색하는 방법?" "ViewModel을 설계 할 때 적절한 단위는 무엇입니까?" "보기에 일치하는 ViewModel이 있어야합니까? 아니면 하나의 ViewModel을 다른보기에서 재사용 할 수 있습니까?" "Slim VM"및 "Thick VM"으로 구성된 ViewModel에 대한 설명이 정말 의미가 있습니다! 시도 중이며 잘 작동합니다. ! 지금까지 :)
클로

@nlawalker 감사합니다! 그리고 또 다른 질문 : 나는 treeView가 있고 TreeViewViewModel을 만듭니다. 그래서, 내 ViewModel에서 : ExpandTree ()와 같은 메소드를 생성한다면. 올바른 방법입니까?
user2545071 jul

와우,이 꽤 좋은 직업 @nlawalker 훌륭한 기사입니다
비벡 Shukla

25

이 매우 유용한 기사 를 소스로 사용하여 View , ViewModelModel에 대한 요약입니다 .


전망:

  • 보기는 창, 페이지, 사용자 정의 컨트롤 또는 데이터 템플릿과 같은 시각적 요소입니다. 보기는보기에 포함 된 컨트롤과 시각적 레이아웃 및 스타일을 정의합니다.

  • 뷰는 DataContext속성을 통해 뷰 모델을 참조합니다 . 뷰의 컨트롤은 뷰 모델에 의해 노출되는 속성 및 명령에 바인딩 된 데이터입니다.

  • 뷰는 뷰와 뷰 모델 간의 데이터 바인딩 동작을 사용자 정의 할 수 있습니다. 예를 들어 뷰는 값 변환기를 사용하여 UI에 표시 할 데이터의 형식을 지정하거나 유효성 검사 규칙을 사용하여 사용자에게 추가 입력 데이터 유효성 검사를 제공 할 수 있습니다.

  • 뷰는 뷰 모델의 상태 변경 또는 UI와 사용자의 상호 작용을 통해 트리거 될 수있는 애니메이션 또는 전환과 같은 UI 시각적 동작을 정의하고 처리합니다.

  • 뷰의 코드 숨김은 XAML에서 표현하기 어렵거나 뷰에 정의 된 특정 UI 컨트롤에 대한 직접 참조가 필요한 시각적 동작을 구현하는 UI 논리를 정의 할 수 있습니다.

참고 :
뷰 모델에는 뷰의 특정 시각적 요소에 대한 명시 적 지식이 없어야하므로 뷰 내에서 시각적 요소를 프로그래밍 방식으로 조작하는 코드는 뷰의 코드 숨김에 있거나 동작에 캡슐화되어야합니다.


모델보기 :

  • 뷰 모델은 비 시각적 클래스이며 WPF 또는 Silverlight 기본 클래스에서 파생되지 않습니다. 애플리케이션에서 사용 사례 또는 사용자 작업을 지원하는 데 필요한 프레젠테이션 논리를 캡슐화합니다. 뷰 모델은 뷰 및 모델과 독립적으로 테스트 할 수 있습니다.

  • 일반적으로 뷰 모델은 뷰를 직접 참조하지 않습니다. 뷰가 데이터를 바인딩 할 수있는 속성 및 명령을 구현합니다. INotifyPropertyChangedINotifyCollectionChanged인터페이스 를 통해 변경 알림 이벤트를 통해 모든 상태 변경을보기에 알립니다 .

  • 뷰 모델은 모델과 뷰의 상호 작용을 조정합니다. 뷰에서 쉽게 사용할 수 있도록 데이터를 변환하거나 조작 할 수 있으며 모델에 없을 수있는 추가 속성을 구현할 수 있습니다. IDataErrorInfo또는 INotifyDataErrorInfo인터페이스 를 통해 데이터 유효성 검사를 구현할 수도 있습니다 .

  • 뷰 모델은 뷰가 사용자에게 시각적으로 표현할 수있는 논리적 상태를 정의 할 수 있습니다.

참고 :
애플리케이션의 논리적 동작에 중요한 모든 것은 뷰 모델로 이동해야합니다. 데이터 바인딩을 통해보기에 표시 될 데이터 항목을 검색하거나 조작하는 코드는보기 모델에 있어야합니다.


모델:

  • 모델 클래스는 애플리케이션의 데이터와 비즈니스 로직을 캡슐화하는 비 시각적 클래스입니다. 애플리케이션의 데이터를 관리하고 필요한 비즈니스 규칙과 데이터 유효성 검사 논리를 캡슐화하여 일관성과 유효성을 보장하는 역할을합니다.

  • 모델 클래스는보기 또는보기 모델 클래스를 직접 참조하지 않으며 구현 방법에 종속되지 않습니다.

  • 모델 클래스는 일반적으로 INotifyPropertyChangedINotifyCollectionChanged인터페이스를 통해 속성 및 컬렉션 변경 알림 이벤트를 제공합니다 . 이를 통해 뷰에서 데이터를 쉽게 바인딩 할 수 있습니다. 개체 컬렉션을 나타내는 모델 클래스는 일반적으로 ObservableCollection<T>클래스 에서 파생됩니다 .

  • 모델 클래스는 일반적으로 IDataErrorInfo또는 INotifyDataErrorInfo인터페이스를 통해 데이터 유효성 검사 및 오류보고를 제공합니다 .

  • 모델 클래스는 일반적으로 데이터 액세스 및 캐싱을 캡슐화하는 서비스 또는 저장소와 함께 사용됩니다.


17

나는 MVVM에 대한이 시리즈에서 생각할 수있는 "일반 영어"로 이것을 작성했습니다 . 특히이 다이어그램 은 가장 간단하고 짧은 설명 일 가능성이 높습니다.

즉, 기본적으로 "모델"은 데이터 또는 비즈니스 규칙입니다. 그것은 어떻게 또는 어디에 사용될 것인지, 특히 어떤 기술이 그것을 사용할 것인지에 대해 정말로 알면 안됩니다. "모델"은 응용 프로그램의 핵심 기능이며 응용 프로그램이 WPF, Silverlight, Windows Forms, ASP.NET 등인지 여부에 대해 걱정할 필요가 없습니다. 순수한 형태의 "그 자체"일뿐입니다.

"보기"는 완전히 기술적 인 부분입니다. MVVM에서 이상적으로는 뷰가 거의 100 % XAML이어야합니다. 이는 유연성에 대한 몇 가지 큰 이점을 제공하기 때문입니다.

그러나 모델의 정보를 현재 기술에서 사용할 수있는 형태로 변환하는 것이 필요합니다. 바로 여기에서 ViewModel이 작동합니다. 예를 들어, 이것은 종종 명령 (로직 실행 용), 구현 INotifyPropertyChanged(데이터 바인딩 지원용) 등 을 포함하는 특정 데이터에 대해 모델 클래스를 "ViewModel"로 "래핑"합니다 . 그게 다입니다. 모델을 만드는 다리입니다. View에서 사용할 수 있습니다.


알았어 고마워. 저는 Model을 객체로 생각하고 ViewModel을 객체를 처리하는 방법으로 생각했습니다. 따라서 뷰가 모델 "객체"를 이해할 수 있습니다. 그러나 나는 이것이 틀렸다고 들었습니다. ViewModel 자체도 객체입니다. 나는 이것이 나를 정말로 혼란스럽게하는 것이라고 생각한다.
RKM 2011 년

@Rosie : 내가 인용 한 시리즈를 읽거나 적어도 훑어 보는 것이 좋습니다. MVC 또는 MVP 등을 이미 이해하고 있다고 가정하지 않는 MVVM에 대한 기사가 거의 없기 때문에 특별히 작성했습니다. 실제로 "단계별"전환입니다.)
Reed Copsey 2011 년

이것을 실현하는 좀비 스레딩 A는 조금 ... 당신의 그림은 VM은 "응용 프로그램 특정 국가가 포함되어 있다고 및 논리 "(내 emph을). VM이 데이터 QA 로직을 포함 할 수 있거나 포함해야한다고 생각합니까? 관련 RssWpfMVVM.csproj는 두 개의 뷰 모델에서 명백한 QA가없는 것 같습니다.
ruffin 2015

1

MVVM에 대한 훌륭한 소개는 여기 Jason Dolinger의 비디오에서 찾을 수 있습니다 . 시작할 때 영상을 꽤 오랫동안 가지고 있었는데 정말 유용했습니다.


1
링크가 죽었
이브라힘 mahrir은

1
@ibrahimmahrir ~ 작동하는 URL에 대한 링크를 업데이트했습니다. 지금 비디오를 다운로드하고 있습니다.
InteXX

0

기본 모델에 대해 일관된 파사드를 제공하는 ViewModel을 빌드하는 것은보기보다 훨씬 복잡 할 수 있습니다. ViewModel 개체 를 빌드하는 방법 에 대한문서는 ViewModel 을 빌드하는 방법을 보여주고, 발생할 가능성이있는 몇 가지 문제와 합리적인 솔루션이 무엇인지 설명합니다. 내가 그것을 읽었을 때 컬렉션을 다루는 섹션이 누락되었지만 여전히 흥미로운 점이 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.