mvvm에서 viewmodel과 model간 연동은 주로 어떻게들 하시나요?

검색을 꽤나 많이 해봤는데요.
view와viewmodel간 연동은 이론이나 방법이나 많이 나오는데.
viewmodel과 model간 연동은 많지가 않네요.
사실 단어로 인해 검색이 어렵기도 하고요.

제가 파악한걸로는 먼저 1:n 이 가능한것으로 봤고요. 실제로는 1:1로 거의 할거라 보긴 합니다.
사용은 model을 만들 때 그냥 class로 만들거나 inotifypropertychanged를 상속하거나 하고
model을 viewmodel에서 속성형태로 생성을 하거나 상속을 해서 쓰기도 하는것 같은데요.
개인적으로 상속은 안좋은 방법이 아닐까 생각을 합니다.
여기까지는 제가 나름 조사하고 분석한 내용 이고요.

질문 1: 저런식이 일반적인지와 어떤 다른 방법은 없는것인지?
질문2: 모델의 데이터가 외부에서 변경이 될 때 model이 viewmodel에 noti를 하는것이 맞는 방법인지 입니다.

읽어주셔서 감사합니다.
혹시 viewmodel 과 model 간 연동을 잘 아시는 분이 계시다면 이 글에 답변 말고 강좌나 팁으로 올리는것도 많은 도움이 되지 않을까 생각합니다.

2개의 좋아요

mvvm을 처음 접할 때 boilerplate에 해당하는 entity들이 inotifypropertychanged를 구현해도 되는지 의문을 갖습니다.

저도 그랬습니다.

그런 고민을 가졌던 이유는 model은 view와 무관해야한다는 생각때문이었습니다.

하지만 inotifypropertychanged는 view와 실제로 무관합니다.

우선은 구별된 interface네임스페이스가 다르지요.

WPF에서 View와 유관한 namespace들은 System.Windows 로 시작하는 경우가 대부분이니까요.

Inotifypropertychanged는 그렇지 않고 System.ComponentModel로 시작합니다.

그러므로 view쪽에서 binding 될 때 inotifypropertychanged를 구현된 모델에 대해 알람을 구독하겠다고 약속했다는 의미죠.

그래서 unittest를 할 때도 inotifypropertychanged를 구현한 클래스를 테스트할 때도 문제없이 동작합니다.

아시겠지만, view와 유관한 project는 unittest 프로젝트에서 dependency를 걸 수 없지요.


communitytoolkit 을 보시면 메커니즘이 observableobject 라는 추상 클래스를 상속받도록 되어 있습니다.

이 observableobject는 소스제네레이터를 통해 귀찮은 ObservableProperty 작업을 대신 만들어내주고 있습니다.

따라서 상속을 해서 사용하는 방법은 이상하지 않고 오히려 간편한 방법이라고 생각합니다.

그리고 notify를 주기 위해선, model도, viewmodel도 모두 observableobject를 구현해야만 합니다.

아니면 직접 구현하거나요…!

3개의 좋아요

viewmodel과 model간 연동만을 위한 방법은 없다는거군요.
그게 알고 싶었습니다.
거의 모든 글들이 view와 viewmodel만을 다루고 있어서 궁금했었습니다.
개인적으로는 있으면 좋겠다는 생각도 했었고요.
방법이 다양한것이 좋긴 하지만 뭔가를 할때 딱딱 나뉘어지는것을 좋아하거든요.

집에서 쉬는 중이라 모바일이다보니 글이 보기 편하지 않으셨을 탠데. 답변 감사합니다.

1개의 좋아요

역시 아시겠지만 viewmodel도, model도 그냥 C# 클래스입니다.

심지어 WPF라면 하나의 View 스타일에 컨트롤마다 DataContext를 따로 가져 갈 수 있으니 View1개에 ViewModel을 여러개 가져갈 수 있다는 말로도 해석이 가능합니다.

그런 부분에서도 ViewModel은 Model하고 크게 차이가 없는 것 같다고 생각을 합니다.

다만 View와 바인딩 되기 때문에 일반적인 클래스들이 갖는 RDD(책임 주도 개발)을 충족하는 특성이 View에 맞춰져있는 클래스인 것이라고 경험해 왔습니다.

저는 그래서 개인적으로 wpf에 사용될 viewmodel은 unittest가 가능하게 만들자는 생각이 있어서 wpf viewmodel 프로젝트를 만들때 일반 C# 클래스 라이브러리 프로젝트로 만듭니다.

뭐 개발하다보면 그렇지 못한 프로젝트가 하나씩 나오긴하지만, 최대한 그렇게 지키려고 노력 중에있습니다.

아마도 그런 글이 없는 이유는, viewmodel은 그냥 model들을 갖고 있기 위함이기 때문일 것이고, 최대한 느슨하게 연결한다고 해도 결국 messenger 같은 걸로 방법이 다 있기 때문에 없는 것이 아닐까하는 개인적인 생각이 있습니다.

봐주셔서 감사합니다!!

2개의 좋아요

뷰모델과 모델은 거의 대부분의 경우, n:n 관계로 봐야 하지 않을까합니다.

그런데, x:x 처럼, 다중성 기반의 관계 표현은 관계형 데이터 베이스의 엔티티 모델 사이의 관계를 표현하기 위한 것입니다. 즉, 테이블 사이의 관계를 표현하는 방식입니다.
아시다시피, 뷰모델은 엔티티가 아니기에, 다중성 관계로 나타내는 직접적인 대상은 아닙니다.

MVVM과 데이터 바인딩은 사실 별개입니다.
데이터 바인딩에서 많이 쓰는 INotifyPropertyChanged 는 Binding 객체 때문에 사용하는 것입니다.
Binding 객체는 데이터 바인딩의 수단 중 하나에 불과한데, 자마린, 마우이, WPF 등 가장 많이 쓰이는 닷넷 프레임워크에서 자주 사용되어서, 마치 데이터 바인딩의 대명사처럼 인식 되는 것 뿐이죠.
예전에는 치약과 "럭키치약"을 동의어로 사용한 것과 유사하다…라고 하면, 너무 올드한가요?

데이터 바인딩은 Binding 과 INotifyPropertyChanged 가 없어도 얼마든지 구현이 가능하고, 심지어 이벤트를 쓰지 않고도 얼마든지 구현이 가능합니다.

예를 들면, Asp.Net Core 웹 페이지는 MVVM 구조이지만, 뷰 → 뷰모델 방향의 데이터 바인딩은 프레임워크에서 처리해주고, 뷰모델 → 뷰 방향의 데이터 바인딩은 레이저 문법을 통한 렌더러에서 처리를 합니다.

MVVM에서 모델을 관리하는 책임은 뷰모델에 있습니다.
즉, “모델의 데이터가 외부에서 변경이 될” 에서 뷰모델이 아닌 “외부” 객체를 허락한다면, MVVM 패턴을 따른다고 할 수 없지 않을까요?

그런데, 여기서 짚고 넘어 가야 할 부분은 모델이 INPC 를 구현하게 만드는 주요 이유는 뷰와 모델 사이에 데이터 바인딩을 위해서인데, 이는 곧 뷰와 모델의 직접적인 결합을 의미합니다.
이 결합은 사실 MVVM이 해체하고 싶은 것으로, 논란의 여지가 있습니다.

3개의 좋아요

Model에서 ViewModel로 Noti를 해야 하지 않을까 생각한 것은
Model에서 보통 WebAPI를 쓰거나 해서 인데요.
댓글을 보고 생각해보니 데이터를 가져 오는 것과 데이터가 달라 진 것을 확인 하는 것은 별개의 것으로 보는 게 맞을 것 같습니다.
결국 ViewModel에서 데이터가 바뀌었는지 확인 후 Model에 Update를 요청하는 방법이 맞지 않나 싶네요. 맞겠죠? ㅎㅎ
물론 거기에 사용될 WebAPI관련 데이터와 API들은 또 잘 만들어야 겠고요.

1개의 좋아요