저는 MVVM을 처음 배울 때부터 굉장히 오랜 시간을 WPF에서 MVVM을 할 때는 코드 비하인드에 코드를 쓰면 안된다고 착각하며 살았습니다.
그런데 객체지향 개념을 배워가고,
캡슐화가 무엇이고,
추상화가 무엇인지 알아가게 되면서,
결국 ‘ViewModel 과 View의 의존성이 결국 끊어지는 것이 중요하구나’ 라고 생각이 들었고, View에 관련된 로직들만큼은 컨트롤들에 있어도 되는구나 생각이 들었었습니다.
사실 MVVM과 관련은 없지만 CustomControl을 개발할 때는 코드 비하인드에 코드를 칠 수 밖에 없습니다.
이런 식으로 제로 코드 비하인드는 개발을 불편하게 하는 요소임에는 분명합니다.
물론 MVVM을 처음 연습할 때는 제로 코드비하인드를 지향하면서 연습하는 것이 좋다고 생각합니다. 그로 인해서 WPF의 다양한 MVVM 스킬에 대해서 성장할 수 있기 때문입니다.
대표적으로 이벤트를 어떻게든 안쓰기 위해 Behavior라는 개념을 배우는 것입니다.
아무튼 View와 ViewModel이 View가 봤을 때도, ViewModel이 봤을 때도, 서로가 서로를 모르도록 의존성이 끊어지는 것이 MVVM의 핵심이구나 하고 알게되었습니다.
그런데 RxUI의 이 개념은 제가 그동안 알아왔던 것을 부정하는 기분이었어서 처음 배울 때 많이 불편했습니다.
Another common misconception is that of separation - while it is very important that the ViewModel have no reference to the View or any of the controls that the View creates, the reverse is not true . The View is free to be very tightly bound to the ViewModel, and in fact, it is often useful for the View to “reach into” the ViewModel via WhenAny, WhenAnyValue and WhenAnyObservable.
DeepL 번역하면
또 다른 일반적인 오해는 분리에 대한 오해입니다. 뷰모델이 뷰 또는 뷰가 생성하는 컨트롤에 대한 참조가 없어야 한다는 것은 매우 중요하지만, 그 반대는 사실이 아닙니다. 뷰는 뷰모델에 매우 긴밀하게 바인딩할 수 있으며, 실제로 뷰가 언제든, 언제든값, 언제든옵저버블을 통해 뷰모델에 "도달"하는 것이 유용할 때가 많습니다.
여기서 관련해서 자료를 좀 찾아보니, MVVM에도 ViewModel First vs View First 개념을 알 수 있었습니다.
ViewModel을 먼저 정의하고 View를 정의하는 관점과, View를 먼저 정의하고 그에 맞는 ViewModel을 정의하는 방법인데요.
ViewModel을 먼저 정의하고 View를 정의할 때는 ViewModel이 View에 의존하지 않게 개발을 시작할 수 있어서 ViewModel에 대해서도 UnitTest를 가능하게 하는 완벽한 의존성 제거를 할 수 있습니다. 또한 여러 View에 DataContext로 ViewModel을 작게 작게 껴넣을 수 있어서 이론상 ViewModel과 View가 1:N 관계가 될 수 있습니다.
View를 먼저 정의하고 ViewModel을 정의하는 관점은 View에 딱 맞는 ViewModel을 설계하므로서 View와 ViewModel이 1:1 관계가 되는 것입니다.
명시적인만큼 유지보수도 쉽습니다. 어차피 ViewModel 이라는 게 View 의 데이터를 다루는 객체라면 유지보수하면서 굳이 분리시켜서 할 필요가 없다는 관점입니다.
이 View First의 관점일 때 RxUI의 지침을 적용하면 ViewModel에 대해서 UnitTest는 불가할지라도 편하게 개발할 수 있는 것입니다.
물론 View First를 할 때도 WPF의 흔한 방식인 DataTemplate의 DataType을 이용해서 ViewModel과 View를 매칭시켜서 ViewModel First를 할 때처럼 코드 비하인드를 최대한 제거하면서 개발할 수는 있지만, RxUI의 관점을 익혀보는 차원에서 지침대로 해보는 것도 좋을 것 같습니다.
여담이지만 제가 RxUI를 쓰면서 지침대로 하지 않으면서 제로 코드비하인드 형태로 개발을 해봤는데 문제없이 동작도 했고 나름 편리하기도 했습니다.
여기서 말하는 지침은 ReactiveWindow를 사용해서 코드비하인드에서 Generic에 ViewModel 타입을 지정하는 것입니다.
이렇게 하지 않고 그냥 RxUI를 쓰더라도 ReactiveWindow같은 RxUI의 컨트롤을 쓰지 않고 WPF의 Binding 문법으로 해도 잘 동작은 했다는 의미입니다.