MVVM을 사용하는 이유

MVVM이 WPF를 비롯한 XAML 기반 플랫폼에서 중요하게 자리 잡고, 계속해서 발전해온 것에는 여러 가지 이유가 있습니다.

DataContext

XAML GUI 바인딩의 가장 핵심 요소인 DataContext 바인딩을 통해, 이 DataContext가 미치는 모든 영역에서 Binding을 손쉽게 할 수 있게 됩니다. 만약 MVVM 기반을 사용하지 않는다면, 이 멋진 DataContext 개념을 제대로 사용할 수 없게 됩니다. 따라서 원하는 부분의 DataContext를 정교하게 관리하는 것이 중요하기 때문에 ViewModel 방식의 개발이 계속해서 선호되고 있습니다.

RelativeSource

WPF는 모든 컨트롤 요소에 DataContext를 설정할 수 있기 때문에, RelativeSource를 통한 계층 탐색이 다양한 상황에서 매우 효과적으로 사용됩니다. 이 역시 MVVM 구조가 아니라면 사용이 컨트롤 요소로만 제한되기 때문에, RelativeSource의 장점을 온전히 활용하려면 MVVM 구조가 필요합니다.

ICommand

Command 바인딩은 ItemsControl 등과 같은 하위 자식 구조에서 RelativeSource와 함께 활용하여 계층적 활용(탐색)을 극대화할 수 있습니다. 다만, 이 또한 ViewModel 구조가 없다면 제한적이고, 사실상 제대로 사용할 수 없게 됩니다.

이 정도만 놓고 봐도 XAML 특성(장점)을 꽤 잃게 됩니다.

반대로 MVVM 개발방식의 단점들도 많이 있습니다. 하지만 다양한 장점들이 단점들을 상쇄하기 때문에 지속적으로 발전해왔던 것이고, CommunityToolkit.Mvvm, Prism과 같은 프레임워크 라이브러리를 통해 계속해서 단점들이 보완되어 왔습니다.

정리하며

MVVM 관련 중요하게 생각해 볼만한 몇몇 요소들을 한번 간추려봤습니다. 물론 이러한 개발 방식에 부담을 느낄 필요는 없습니다. 저도 개인적으로 수년간 MVVM 기술 의존 없이도 재미있게 개발했었고, 실제 현업에서도 MVVM 없이, 심지어는 코드비하인드만으로 만들어진 프로젝트도 꽤 많이 봐왔습니다.

또한, 일반적인 전통 방식으로도 다양하게 개발해본 경험이 아주 좋은 자산이 되었습니다.

사실 MVVM의 사용 유무, 그리고 사용 방법보다도 XAML의 주요 메커니즘 특성을 이해하는 것이 더 중요하다고 생각합니다. 중요한 키워드는 고작 10개 정도밖에 안됩니다. 이 안에 WPF를 비롯한 모든 XAML 크로스플랫폼의 메커니즘을 관통하는 요소들이 다 얽혀 있으니, 본질에 대해 더 비중 있게 관심 갖고 살펴보시기를 권합니다.

  • DataContext
  • RelativeSource
  • DependencyProperty
  • Control
  • ContentControl
  • ItemsControl
  • Template
  • ContentTemplate
  • ItemTemplate (ContentPresenter)
  • DataTemplate
  • IValueConverter

결국 MVVM은 이런 XAML의 특성을 가장 잘 활용할 수 있도록 도와주는 개발 방법일 뿐입니다.
먼저 XAML의 본질적인 구조와 메커니즘을 이해하고 나면, MVVM은 자연스럽게 필요성을 느끼게 될 것이고, 훨씬 수월하게 받아들일 수 있을 것입니다.

15개의 좋아요

구글 의견 : UI 있는 응용 프로그램을 만들 때, MVVM을 사용하면 어떤 점이 좋은가요?
(When building an application with UI, what are the benefits of using MVVM?)

UI 애플리케이션을 구축할 때 모델-뷰-뷰모델(MVVM) 아키텍처 패턴을 사용하면 테스트 용이성, 유지 관리 용이성, 코드 재사용성 향상 등 여러 가지 주요 이점을 얻을 수 있습니다. MVVM은 애플리케이션을 모델(데이터 및 비즈니스 로직), 뷰(사용자 인터페이스), 뷰모델(모델과 뷰 사이를 중재)의 세 부분으로 나누어 관심사를 명확하게 분리합니다.

이러한 이점을 더 자세히 살펴보겠습니다.

관심사 분리:
MVVM은 애플리케이션의 로직을 별도의 구성 요소로 명확하게 분리합니다. 모델은 데이터와 비즈니스 규칙을 처리하고, 뷰는 UI를 표시하며, 뷰모델은 모델과 뷰 간의 상호 작용을 관리합니다. 이러한 분리를 통해 다른 부분에 영향을 주지 않고 애플리케이션의 개별 부분을 더 쉽게 이해하고, 수정하고, 테스트할 수 있습니다.

테스트 용이성 향상:
MVVM은 프레젠테이션 로직(뷰모델)과 UI(뷰)를 분리하여 뷰모델의 단위 테스트를 더 쉽게 수행할 수 있도록 합니다. 뷰모델의 로직을 뷰와 별도로 테스트하여 비즈니스 규칙이 제대로 작동하는지 확인할 수 있습니다.

향상된 유지 관리성:
MVVM의 관심사 분리 덕분에 애플리케이션 유지 관리 및 업데이트가 더욱 쉬워졌습니다. UI 변경은 기본 비즈니스 로직(모델)이나 뷰모델에 영향을 주지 않고 수행할 수 있습니다. 마찬가지로, 뷰모델의 계약(API)이 일관되게 유지되는 한 비즈니스 로직 변경은 UI에 영향을 주지 않고 수행할 수 있습니다.

재사용성 향상:
뷰모델은 여러 뷰에서 재사용될 수 있으며, 특히 유사한 데이터 및 로직 요구 사항을 가진 애플리케이션에서 더욱 그렇습니다. 이를 통해 코드 중복을 줄이고 공통 기능의 유지 관리 및 업데이트를 더욱 쉽게 수행할 수 있습니다.

간소화된 UI 개발:
MVVM의 핵심 기능인 데이터 바인딩은 뷰모델과 뷰 간의 데이터를 자동으로 동기화하여 UI 개발을 간소화합니다. 이를 통해 UI를 수동으로 업데이트할 필요가 없고, 보일러플레이트 코드도 줄어듭니다.

병렬 개발 촉진:
MVVM을 사용하면 개발자는 뷰와 뷰모델(또는 모델)을 동시에 작업할 수 있습니다. 디자이너는 UI에 집중하고 개발자는 기본 로직을 작업할 수 있어 개발 주기가 단축됩니다.

복잡한 애플리케이션 지원:
MVVM은 코드를 체계적이고 관리하기 쉽게 유지하여 필요에 따라 애플리케이션을 쉽게 확장할 수 있도록 해주므로 크고 복잡한 애플리케이션을 구축하는 데 적합합니다.

(* 영어로 묻고 영어 답을 구글 번역했습니다.)

3개의 좋아요

데이터 바인딩은 "XAML 태그"와 “C# 코드” 사이에 데이터를 동기화해주는 기술이고, MVVM은 소프트웨어 구조론입니다.

  • MVVM 은 WPF 가 제공하는 데이터 바인딩 관련 객체가 없어도 적용 가능하고,
  • 데이터 바인딩은 ViewModel 뿐만 아니라, View, Model, Controller, Presenter, 심지어 서비스 객체에도 적용할 수 있기 때문에,

이 둘 사이에는 아무런 상관이 없다고 할 수 있습니다.

오히려, 데이터 바인딩의 유연성 때문에, MVVM 등

디자인 패턴을 사용하지 않아도 되는 이유

가, 이 글의 제목으로 더 어울리는 것은 아닌 지 하는 생각이 듭니다.

그럼에도 불구하고 WPF에 MVVM 이라는 디자인 패턴을 사용해야 하는 이유가 있어야 하지 않을까요?

4개의 좋아요

찰스 패졸드 책을 통한 MVVM 학습

찰스 패졸드의 "Applications = Code + Markup"는 2006년 WPF 런칭과 함께 나온 책으로, WPF 철학을 가장 깊이 있게 다루는 책 중 하나입니다. 그는 윈도우 기반 개발 플랫폼을 단계적으로 섭렵해온 윈도우 개발의 아버지 중 한 명으로, 데스크톱 애플리케이션에 대한 통찰력이 책 전반에 녹아있습니다.
이 책에서는 MVVM을 직접적으로 다루지는 않지만, Binding, DataContext, 터널링/버블링 이벤트 체계 등 MVVM의 기반이 되는 모든 기술을 XAML과 Code를 통해 풍부하게 설명합니다. 그의 차원이 다른 통찰력으로 WPF를 해석하고 있어, 깊이 있는 학습을 원할 때 고민 없이 추천할 수 있는 특별한 책입니다.

뷰모델 재사용에 대한 고민

MVVM을 더 효과적으로 사용하기 위해 뷰모델 재사용을 고려하는 경우가 있습니다. 대표적으로 두 가지 상황이 있죠:

  • 하나의 동일한 뷰를 여러 개 만들어야 하는 경우
  • 여러 뷰를 하나의 뷰모델로 사용하는 경우

하지만 경험상 이런 경우들에서는 뷰모델을 재사용하지 않는 것이 좋습니다. 뷰모델은 단 하나의 인스턴스만 관리하는 것이 관리적 측면에서나 개발 단계에서도 더 효과적입니다.

예를 들어 디버깅 시에 여러 뷰가 하나의 뷰모델을 공유한다면, 각각의 뷰에 대한 디버깅 제어가 어려워지고 인스턴스마다 특성이 달라 예외처리 구간이 많아집니다. 오히려 MVVM 구조가 복잡해져 버리죠.

이런 경우에는 ItemsControl 기반으로 뷰의 수준을 Item 수준으로 낮추는 것이 더 효과적입니다.

재사용이 필요하면서도 뷰모델을 1:1로 유지하고 싶다면, 비슷한 유형에 대응하는 베이스 클래스를 만들어 상속받는 방법을 추천합니다.

결론적으로 뷰와 뷰모델은 1:1 관계로 유지하는 것이 가장 안전합니다. 물론 이것은 일반적인 상황이며, 모든 케이스에 100% 적용되는 것은 아닙니다.

정리하며

찰스 패졸드의 책은 가장 훌륭한 WPF 책 중 하나이며, 좀 더 깊게 배우고자 하는 욕구가 생길 때 접하시기를 권합니다.

그리고 MVVM에서 재사용이 필요한 경우에는 직접 재사용하기보다는 상속과 추상화를 통해 그룹화하되, 뷰와 뷰모델은 1:1로 맞춰 사용하는 것이 좋습니다.

물론 이런 원칙들이 모든 상황에 동일하게 적용될 수는 없습니다. 각 애플리케이션의 설계 상황과 요구사항에 맞게 유연하게 적용할 수 있는 포용력이 필요합니다. 때로는 이론적 완성도보다 프로젝트의 현실적 제약이나 팀의 역량을 고려한 선택이 더 현명할 수 있죠.

특히 기존 프로젝트의 경우에는 더욱 신중해야 합니다. 이미 잘 돌아가고 있는 기존 패턴을 무리하게 MVVM으로 바꾸려고 시도하는 것보다는, 현재 구조를 존중하면서 장기적으로, 또는 새로은 프로젝트에서 개선해나가는 것이 훨씬 안전하고 효과적입니다. 기존 설계를 전면 부정하고 뒤엎는 것은 오히려 프로젝트에 가장 큰 악수가 될 수 있습니다.

3개의 좋아요

@BigSquare 앗 좋은 해석입니다.

제목도 내용도 의도적으로 모호하게 의도한 것이 맞습니다.

그리고 MVVM은 WPF를 통해 발전된 개발방법론으로 제가 언급한 DataContext 등의 몇몇 키워드와 매우 밀접하게 설계되었기 때문에 위 키워드들을 MVVM과 연계하여 비중 있게 언급한 것입니다.

내용은 천천히 빌드업해 나가겠습니다. 다루었으면 하는 내용도 적어주시면 좋습니다.

4개의 좋아요

많은 분들이 "MVVM"과 "데이터 바인딩"을 구분하지 않고 혼용해서 사용하고 있는 점을 말하고 싶었습니다. 심지어, 뷰모델에 비지니스 로직이 들어 가야 한다고 생각하는 분들도 아직 많은 것 같습니다.

사실 저도 Xamarin 으로 C# 을 시작했을 때, MVVM 을 처음 경험했는데, 동일한 오해를 한동안 가지고 있었습니다.

그런데, 4년 전까지만 해도 그렇게 많던 MVVM 관련 글들이 지금은 마소에서 많이 사라진 것 같습니다. 언급하신 Charles Petzold의 책과 글들도 지원이 끝난 문서로 분류되었고, 심지어, (훨씬 유연한) 데이터 바인딩을 제공하는 블레이저의 문서에는 “MVVM” 이라는 단어가 한번도 나오지 않습니다. 블레이저 뿐만 아니라 데이터 바인딩을 제공하고 MVVM 구조로 설계된 다른 프레임워크도 WPF 만큼 강조하지는 않습니다.

우리에게 필요한 건 데이터 바인딩 그 자체이지, 그것과 어떤 패턴을 연결할 필요는 없다는 점을 마이크로소프트도 깨달은 건 아닌가하는 생각이 듭니다.

사실, 거의 모든 뷰에는 어떤 모델(들)이 필요하기는 합니다. MVVM에서는 그걸 뷰모델이라고 부르기는 하지만, 그게 MVVM의 주장처럼 재사용성이나 관심사의 분리를 위해서라기 보다는 그냥 코드 구조 상 필요할 뿐이라, 아래의 내용에 100% 동의합니다.

이는 뷰에게 중요한 건 좋은 설계 철학이나 OOP의 황금 원칙이 아니라 잦은 변경 요구에 대한 신속한 대응과 성능이기 때문이라서 그런 것 같습니다.

6개의 좋아요

@BigSquare 좋은 관점입니다.

공감해주신 내용과 더불어, MVVM은 WPF가 출시된 2005년 이후 적어도 20년 가까이 전에 WPF 구조에 맞게 설계되었기 때문에 MVVM이 지향했던 재사용성, 관심사 분리 등의 여러 초기 컨셉들이 조금씩 변형되거나 요즘 트렌드에 맞지 않을 수 있다고 생각합니다. 저도 @BigSquare 님의 통찰력에 크게 공감합니다.

또한 변화와 트렌드에 맞춰 Prism을 시작으로 다양한 프레임워크와 라이브러리들도 함께 발전해왔죠. 이를 통해 MVVM의 무거운 짐들을 덜어내고 더욱 가볍게 구현할 수 있게 되었습니다. 특히 뷰 주입, 의존성 주입, 싱글턴 패턴 등을 통해 MVVM에서 개발자가 직접 해야 했던 많은 일들이 자동화되고 간소화되었죠.

저도 이러한 자산들의 시행착오와 발전 과정을 함께하며 Jamesnet.Wpf부터 시작해서 Jamesnet.Foundation, Jamesnet.Platform.Wpf/OpenSilver/Uno 등 플랫폼 간 마이그레이션에 유연하게 대응하는 라이브러리를 만들어 동료들과 함께 리그 오브 레전드 같은 재미있는 결과물들을 만들어내고 실제로도 여러 분야에서 좋은 자료로 쓰임을 받고 있기도 합니다.

이제 AvaloniaUI를 비롯해 Uno Platform, OpenSilver와 같은 XAML 플랫폼들도 WPF의 제약을 벗어나 계속해서 새롭게 진화하고 있습니다. MVVM은 실제로 부족한 부분을 기술적으로, 방법론적으로 계속해서 보완하며 정말 다양한 분야에서 활발히 사용되고 있습니다.

그리고 마이크로소프트는 과거 직접 관리하던 Microsoft.Toolkit.Mvvm을 CommunityToolkit.Mvvm으로 리브랜딩하면서 관리 포인트를 오픈소스 진영으로 이관한 것일 뿐, XAML 기반 플랫폼에서는 여전히 중요하며 .NET Foundation의 대표적인 핵심 자산 중 하나입니다.

과거 WPF, Xamarin, UWP 등의 특정 플랫폼을 타겟으로 했던 Microsoft.Toolkit.Mvvm과 달리, CommunityToolkit.Mvvm은 더 이상 플랫폼을 구분하지 않고 모든 XAML 기반 플랫폼에서 동작합니다. 이러한 이유로 Microsoft라는 단어를 빼고 Community라는 단어로 변경하였기도 합니다. (라고 합리적 추측…)

지원 플랫폼:

  • WPF
  • Xamarin
  • UWP
  • WinUI3
  • MAUI
  • AvaloniaUI
  • Uno Platform
  • OpenSilver

그리고 찰스 페졸드 관련 지원에 관한 내용은 제가 정확히 모르겠네요. 그가 Xamarin 팀에 있었고 이후 MAUI 등 XAML 기반 플랫폼에 여러 방면으로 영향력을 보였고, 그의 책은 여전히 가치가 높습니다. 실제로도 정말 대단합니다. 20년 전 어떻게 그 방대한 범위를 다 아우를 수 있었는지… 어느 페이지를 펴도 재밌습니다. (물론 재미 포인트는 사람마다 다르겠지만요 :blush:)

또한 MVVM은 XAML 기반 플랫폼에 특화되어 있어서 Angular나 Blazor의 바인딩과는 직접적인 관계가 없지 않을까 싶습니다. (잘 모르는 분야라 언급하기가 조심스럽네요… 제 개인적인 생각입니다.)

그런데 제가 기억하기로는 Angular의 {{바인딩}} 문법이 MVVM과 유사하다는 비교가 종종 있었고, Blazor 역시 초기에 WPF와 MVVM에 비유되며 의도적으로 바이럴되었던 것 같습니다 (제가 그런 비교를 했을 수도 있고요…). 어디까지나 제 기억에 의존한 이야기이지만, 실제로는 이러한 기술적 구분을 크게 신경 쓰지 않고 사용하는 경우도 많았을 것 같습니다.

정리하며

마지막으로, 이 글은 XAML 기반에서 MVVM을 사용하는 이유에 대한 내용으로 이해해주셨으면 좋겠습니다. 또한 숨겨진 의도는 MVVM을 잘 받아들이기 위한 가이드라인을 제시하는 것입니다.

XAML 플랫폼에 한정된 내용이니 부족하더라도, 제가 계속해서 이 시리즈를 완주할 수 있도록 응원 부탁드립니다.

4개의 좋아요

MVVM과 데이터 바인딩을 구분 없이 사용하는 경우가 많은 건 사실이고, 그로 인해 뷰모델이 곧 로직의 중심이어야 한다는 오해도 여전히 많다고 생각합니다. 말씀처럼 마이크로소프트 공식 문서에서 “MVVM”이라는 용어의 노출 빈도가 줄어든 건 맞지만, 그렇다고 해서 MVVM이 사라졌거나 마이크로소프트가 이를 부정하는 흐름은 아닙니다.

실제로, 최근에는 CommunityToolkit.Mvvm이 공식적으로 MVVM 구조를 지원하는 핵심 라이브러리로 자리 잡으면서 관련 가이드는 Toolkit 중심으로 이동한 경향이 있습니다. 공식 문서에서도 WPF, WinUI, MAUI 등의 MVVM 구현 방법은 Toolkit 위주로 설명되고 있습니다.

또한, Blazor는 MVVM이 아닌 컴포넌트 기반 모델을 따르고 있어서 구조적으로 MVVM과 다르며, ViewModel이라는 계층 없이도 양방향 바인딩과 상태 관리를 해결할 수 있기 때문에 “MVVM”이 문서에서 등장하지 않는 것이 자연스럽다고 볼 수 있습니다.

요약하자면,

  • WPF를 비롯한 XAML 계열은 여전히 MVVM이 중요하게 다뤄지고 있으며
  • Toolkit(MVVM Toolkit)으로 관련 자료와 공식 지원이 이전되었고
  • 마이크로소프트가 “MVVM을 버렸다”기보다는, 플랫폼의 특성에 따라 강조점이 달라진 것이라고 보는 게 더 정확할 것 같습니다.
5개의 좋아요

그 툴킷이 거의 모두 데이터 바인딩과 연관된 객체들의 집합임에도 불구하고, 이름이 “MVVM” 이어서, 용어의 혼용을 유발하는 주 원인인 것 같습니다.

MVVM 은 뷰 우선 디자인 패턴입니다.
이는 종속성 트리의 최상단에 뷰가 있음을 의미합니다.

V → VM → M

이와 다른 패턴, 예를 들면 MVC는, 뷰가 있음에도, 콘트롤러 우선 디자인 패턴이라, 컨트롤러가 종속성 최상단입니다.

C → V, M

"블레이저는 컴포넌트 기반"이라는 말 자체가 뷰 우선 구조임을 나타내고, MVVM 을 적용하기 좋다는 의미입니다. 이는 블레이저나 기타 닷넷의 프레임워크 뿐만 아니라, 다른 언어의 프레임워크도 동일합니다.

개인적인 생각으로, xaml 기반의 데이터 바인딩은 매우 번잡스러운 것 같습니다.
커뮤니티에서 그 번잡성을 완화하려는 노력까지 할 정도로 말이죠.

그런데, 데이터 바인딩의 번잡함 뿐만 아니라, 윈도우 전용, IoC 미지원이라는 단점이 있음에도 WPF 를 사용하는 이유는 (렌더링) 성능이 아닐까 합니다.
고속 게임 엔진을 사용하지 않는 어플리케이션 수준에서 WPF 만큼 체계적이고 성능이 좋은 프레임워크는 아직 없는 듯 보입니다.

2개의 좋아요

좋은 의견 감사합니다! 다만, 몇 가지 오해의 소지가 있어보여 보완 드립니다. :bowing_man:

:white_check_mark: MVVM은 “뷰 우선” 패턴인가요?

MVVM(Model-View-ViewModel)은 기본적으로 뷰 우선(View-First) 구조도, 뷰모델 우선(ViewModel-First) 구조도 아닌 "역할 분리 중심"의 디자인 패턴입니다.

  • 종속성 방향(V → VM → M)은 바인딩 구조를 설명할 수는 있지만, 그 자체가 “우선순위”를 의미하진 않습니다.
  • 실제로는 ViewModel이 View를 전혀 알지 못하도록 설계되며, 이는 의존성 역전(Dependency Inversion) 원칙에 가깝습니다.
  • 따라서 MVVM을 “뷰가 최상단인 구조”라고 보는 것은 다소 축약된 해석입니다.

:white_check_mark: Blazor는 MVVM에 적합한가요?

Blazor는 MVVM을 기본으로 삼는 구조가 아니며, 컴포넌트 기반 상태 주도 모델을 따릅니다.

  • Razor 컴포넌트 내에서 UI와 로직(State/Method)이 혼합된 구조를 가지고 있고, ViewModel이라는 독립 계층은 없습니다.
  • 물론 MVVM 스타일로 구조화할 수도 있지만, 이는 자연스러운 방식은 아니며 오히려 복잡도를 증가시킬 수 있습니다.

:white_check_mark: CommunityToolkit.Mvvm이 MVVM과 바인딩을 혼동시키나요?

  • CommunityToolkit.Mvvm은 MVVM을 구현하기 위한 도우미 라이브러리일 뿐, MVVM 그 자체는 아닙니다.
  • MVVM 패턴은 라이브러리 없이도 충분히 구현 가능합니다.
  • 따라서 MVVM이라는 개념이 이 툴킷으로 인해 오염되었다기보다는, MVVM을 도구의 레벨로 이해하는 관점이 혼동의 원인이라고 생각됩니다.

:white_check_mark: WPF는 성능 때문에 사용하는가?

  • WPF가 여전히 사용되는 이유는 렌더링 성능뿐 아니라, 강력한 데이터 바인딩 시스템, 스타일/트리거 시스템, MVVM 친화성 등 UI 프레임워크로서의 완성도도 큰 몫을 차지합니다.
  • 또한 IoC를 기본 지원하지 않는다고 하셨는데, 구조적으로 IoC 컨테이너(예: Prism, Autofac 등)와의 통합은 매우 자연스럽게 이루어질 수 있습니다.

:compass: 요약하자면, MVVM은 “우선순위 구조”로 해석되기보다는 각 계층의 책임 분리와 바인딩 구조로 이해하는 것이 더 정확하며, 이를 Blazor나 다른 프레임워크에 적용할 때도 핵심 원칙에 대한 이해가 선행되어야 한다고 생각합니다.

p.s따로 논의를 여시는게 좋을거같습니다. @jamesnet214 님의 Slog이기에…
p.s 얘기가 점점 산으로 가는 것 같습니다 따로 글을 올려서 얘기를 하시는게 좋을 것 같습니다.

3개의 좋아요

역할 분리는 MVVM 만 요구하는 것은 아닙니다.
모든 디자인 패턴의 주장이 역할을 분리하라는 것입니다.

복잡도 때문에 뷰모델을 사용하지 말아야 한다면, WPF에서도 뷰의 속성에 데이터 바인딩을 걸수 있는데, 굳이 뷰모델을 쓸 이유가 없겠죠.

이 정도도 없는 UI 프레임워크가 있을까요?

p.s. 왠지 AI 답변을 붙여 놓은 듯한 느낌을 받았습니다.
아니라면, 죄송합니다만, 맞다면 자제 부탁드립니다.

1개의 좋아요

엄청난 칭찬임…
AI 급 임
기본에 충실한 AI
아무튼 그러함…

2개의 좋아요

BigSquare님의 경험을 토대로 한 본문은 신선한 충격이었습니다. 다만 의견 중에 궁금한 것과 반론하고 싶은 것이 몇 가지 있습니다.

데이터 바인딩이 있기에 무조건 MVVM 패턴을 사용해야 한다는 명제는 거짓이지만 뷰와 뷰모델의 느슨한 결합을 위해 데이터 바인딩은 MVVM 패턴의 달성에는 필수 불가결인 요소라고 생각했습니다. 혹시 데이터 바인딩 없이 MVVM을 적용하는 방법이 무엇일까요?

View-First 패턴이 많은 프레임워크에서 주로 사용되는 것이 사실이나, DataTemplate을 통한 ViewModel-First 패턴도 충분히 채용할 수 있습니다. 종속성의 방향과 관계없이 "무엇을 먼저 초기화하느냐"가 View-First 패턴을 판가름합니다. Blazor는 View-First 패턴이 맞습니다. 마크업에 partial class의 멤버를 바인딩해주는 것이기 때문에 논쟁의 여지 없이 뷰만 초기화됩니다. 다만 View-First 패턴인 것과 MVVM 적용의 용이성에 큰 연관이 있다고 보이진 않습니다.

복잡도보다 관심사의 분리가 근거에 좀 더 적절한 것 같습니다. WPF는 컴포넌트의 개념이 없기에 인터렉션에 대한 모든 책임을 컨트롤이 가지고 있어야 합니다. 그렇다면 브라우저와 컴포넌트 등이 인터렉션의 책임을 양분하는 Blazor보다 뷰와 서비스 로직 간의 분리가 더더욱 중요할 수밖에 없습니다. 그 때문에 둘의 느슨한 결합을 위해 DataContext와 뷰모델이라는 거추장스럽게 보일만한 것들을 애써 사용해야만 합니다.

끝으로 [MVVM 패턴을 사용하는 이유]라는 제목은 꽤 자극적이지만 WPF의 성격을 찬찬히 살펴보고 나면 MVVM을 채용하는 것은 지극히 합리적입니다. 디자인 패턴이라는 것이 개개인의 관점에서 족쇄지만 협업을 통해 만들어지는 엔터프라이즈 앱에서는 효과적인 의사소통의 수단이 되기도 하고요. WPF는 그런 측면에서 잘 조율되었기 때문에 플랫폼에 종속적이고, 못생긴 기본 컨트롤, 유기당한 건가 싶은 띄엄띄엄한 지원에도 살아남은 거겠죠.

11개의 좋아요

저의 언급을 다시 살펴 보시면 "WPF 가 제공하는 데이터 바인딩 관련 객체들"입니다.
그 핵심은 Binding 클래스라고 할 수 있습니다.

xaml에서 Binding 안 쓰고 뷰의 데이터를 코드가 읽거나 코드의 데이터를 뷰에 반영하는 것을 모르시지는 않을 것이라 생각됩니다.

뷰 우선은 우리가 작성하는 커스텀 코드의 실행흐름이 뷰에 의해 결정된다는 의미입니다. WPF 에서 앱 코드의 시작점은 App.xaml 이고, 블레이저는 App.razor로, 둘 다 뷰이고, 그곳에서부터 뭐라도 코드를 적는 것입니다.

MVC에서는 컨트롤러가 그 지위를 갖습니다.

그런데, 객체의 생성 (초기화) 시점과 종속성(의존 방향)은 다른 문제라 할 수 있습니다.

주인 객체를 (먼저) 초기화할 때, 종속 객체를 (나중에) 생성할 수도 있지만, IoC 기법을 도입하면 종속 객체가 먼저 생성되어 주인 객체를 생성할 때 주입되므로, 생성 순서가 달라집니다. 또한, 앱의 생애 주기 동안 잠깐 의존하는 객체, 대표적으로 메서드의 매개 변수로 전달되는 객체는 생성 시점에 아무런 연관성이 없습니다.

결론적으로, 의존 관계인 두 객체의 생성 시점은 관계에 아무런 영향을 미치지 못합니다.

많은 분들이 "컴포넌트"가 뭔가 다를 것이라 생각하시는 것 같습니다.
그 용어는 뷰의 명칭으로 재사용성을 강조한 것에 불과합니다.

WPF 로 치자면, 윈도우인데, 다른 윈도우의 자식 콘트롤로도 사용될 수 있다는 의미 정도입니다.

// AWindow.xaml
<StackPanel ..
   <BWindow ...
   <CWindow...

이 점을 빼면, 로직의 처리, 파일 구조는 마소의 다른 뷰들과 큰 차이가 없고 데이터 바인딩도 있습니다.

그 때문에 둘의 느슨한 결합을 위해 DataContext와 뷰모델이라는 거추장스럽게 보일만한 것들을 애써 사용해야만 합니다.

“DataContext” 자체 보다는, 그것을 떠 받치는 Binding 객체는 바인딩 소스의 형식(Type)과 상관 없이, 오로지 속성의 이름(Binding Path)으로만 동작하기에, “느슨한 결합” 이라는 의미는 맞습니다.

그런데, 느슨한 결합, 다시 말하면, “바인딩 소스의 형식과 상관 없기” 때문에 Path가 "뷰모델"에만 있어야 하는 것은 아닙니다. 실제로도, 그 Path가 모델에 있어도, 뷰 자신에게 있어도, 하다 못해 서비스에 있어도 데이터 바인딩은 잘 됩니다.

그런 이유로, WPF 데이터 바인딩과 MVVM은 아무런 상관이 없다고 말씀드린 것입니다.
다만 이것이 MVVM을 도입할 필요는 없다는 의미도 아닙니다. 디자인 패턴의 도입은 코드 작성자의 선택의 문제이기 때문입니다.

1개의 좋아요

다른 분들의 의견은 어떠신가요?

@jamesnet214 님의 slog에 다른 의견들이 계속 이어지는 것 같아서 조심스럽습니다만 제가 읽어보고 판단하기로는 @BigSquare 님께서는 그저 첫번째의 데이터 바인딩 자체와 MVVM을 분리해서 말하려는 딱 저 명제만을 말씀하시고 싶으신 것 같습니다. 그래서 덧붙여서

이렇게 말씀하신 것 같습니다. 이 글은 WPF가 MVVM을 사용하는 것을 강요하니까 그러면 안 된다는 글도 아니고 @BigSquare 님의 글 취지도 그런 건 아니라고 밝히고 있습니다.

토론이 과잉되는 것 같아서 관리자로서 우려되는 점은 있긴하지만 정리차원에서 저도 하나 남겨보자면 @BigSquare 님께서 말씀하신 DataBinding이 굳이 ViewModel 일 필요는 없다는 부분은 WPF를 이제 막 사용하는 코드에서도 볼 수 있습니다. 많이들 접하셨을 텐데 바로 아래같 은 것입니다.

partial class MainWindow : Window
{
    public MainWindow()
    {
         InitializeComponent();
         Loaded += Window_Loaded;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
         DataContext = this; // 이제 MainWindow에서 정의하는 Property들과 Binding Path로 바인딩 가능.
    }
}

WPF를 MVVM 형태로 조금이라도 다뤄보신 분들은 위와 같은 코드를 좋아하진 않으실 것 같습니다. 저 역시 그렇습니다.

하지만 이것은 문법적으로는 문제가 되지 않습니다. 그런데 일반적으로 퍼진…공용화된 WPF의 MVVM 코드 형태가 위와 같지 않기에 유지보수에서 문제가 발생합니다. WPF에서 MVVM 도입해서 쓰는 이유는 위에 의견이 나열된 대로 관심사의 분리를 하기 위한 개발팀의 선택이고, 개발팀의 마지노선 지식 수준이기 때문일 것이고 하나의 프로토콜, 약속이기 때문일 것입니다.

제가 알기로는 WPF가 탄생하면서 MVVM의 역사도 함께 시작된 것으로 알고 있습니다. WPF와 MVVM의 나이가 같다는 것이죠. MS에서 출발한 개념이고 다른 UI 프레임워크들에 영감을 준 형태라고 생각합니다. 그러다보니 MVVM을 통한 DataBinding 개념이 WPF에 뿌리내렸을 것이고 혼용하는 것이 WPF를 주로 쓰는 저같은 사람들에게는 당연한 일일지 모르겠습니다. 하지만 WPF의 MVVM으로 부터 영감을 받은 UI 프레임워크들은 WPF와 비슷하겠지만 완벽하게 같은 형태는 아닐 것이기에,

WPF, DataBinding, ViewModel

을 1 set으로 보기보단 분리해서 보는 시각은 필요해보입니다.

그렇기 때문에 WPF에서 DataBinding은 ViewModel이 없어도 가능하니까 분리해서 보는 관점도 필요하다고 생각합니다. 저는 @BigSquare 님의 관점이 이 관점 같다고 이해했습니다. 명제가 흐려지는 것 같아서 남겨봅니다. 실례했습니다. @jamesnet214 님.

이후 의견은 @이광석 님의 말씀처럼

혹시 @BigSquare 님께서 추가 의견이 있으시다면 부탁의 말씀으로 다른 글에서 토론해보시는 게 어떨까 제안드립니다. 그 방법이 생각을 더 정확하고 풍부하게 표현할 수 있을 것 같습니다.

3개의 좋아요

활발한 논의를 이끌어주신 커뮤니티 멤버 여러분들께 감사드립니다. 다만 현재 논의가 이루어지고 있는 카테고리는 Slog 카테고리로, 이 카테고리는 느리게 이어서 작성하는 블로그 라는 점을 고려하셔서, 토론의 내용이 길어진다고 생각되시면 별도의 스레드에서 토론을 진행해주시는 것을 권해드리고 있습니다.

이에 원 저자께서 계속해서 본인의 글을 이어서 쓰실 수 있도록 토론 스레드를 분리해서 논의해주실 것을 권고드립니다.

고맙습니다.

7개의 좋아요