-
FrontEnd의 관점으로 바라본 MVVMWeb Programming 2024. 1. 10. 14:56반응형
MVVM의 등장배경
기존 디자인 패턴(MVC, MVP)등에서 단점으로 이야기되는 View의 의존성을 최소화하기 위해 등장
MVVM 기본
MVVM은 Model, View, ViewModel의 머리만 따와서 명명되었습니다.
기존의 MVC 패턴에서 화면이 복잡해질수록 Controller가 비대해진다는 문제와 View가 Controller와 강하게 결합되어 있는 문제를 해결하기 위해 MVVM 패턴이 제안되었습니다.
MVVM에서 가장 중요한 개념이라면 Observer 패턴을 통한 Data Binding이라고 할 수 있습니다.
기존의 Controller에서 Model의 변경에 따라 View를 직접 변경해주었다면 MVVM은 바인딩을 통해 이를 자동으로 업데이트 해줍니다.
FrontEnd에서의 MVVM
프론트엔드에서 MVVM 기반의 프레임워크로 대표되는 Vue 프론트에서 MVVM 패턴이 본격적으로 등장한건 AngularJS가 등장하면서 부터입니다.
기존의 웹 개발 패턴은 SSR + jQuery 등으로 전체적인 렌더링은 서버에서 하되 부분적인 갱신은 jQuery로 수정하는 jQuery가 일종의 Controller 역할을 하는 MVC 패턴의 일환이었습니다.
// Input Binding With jQuery <input type="text" class="name" /> <div class="target"></div> <script> $( ".name" ).on( "change", function(e) { $(".target").text(e.target.value) } ); </script>
jQuery로 DOM을 직접 조작하는 방식은 코드가 훨씬 길어지고 효율이 떨어졌기에 이때 MVVM 패턴과 함께 AngularJS가 등장했습니다.
// Input binding With AngularJS <input type="text" ng-model="name" /> <div>{name}</div>
이제 UI에 데이터를 직접 바인딩해서 직접적인 DOM 조작 없이 부분 갱신이 가능해졌습니다. View에 변수를 바인딩하고 Model이 변경되면 자동으로 변수의 변경이 View에도 반영이 됩니다. 프레임워크가 MVVM 패턴의 ViewModel을 하고 있다고 해석할 수 있습니다.
이떄부터 Angular 이외에도 Vue, Svelte 등의 다양한 프레임워크가 MVVM 패턴과 양방향 바인딩을 기반으로 나오기 시작했습니다.
(React의 경우에도 MVVM 패턴에서 착안하여 만들어지긴 하였으나 위의 프레임워크와는 다르게 단방향 바인딩을 사용하며 Flux라는 파생적인 패턴과 유사하다고 볼 수 있습니다.)
JavaScript로 MVC 패턴과 MVVM 패턴 비교
개념적으로는 MVC와 MVVM이 정리가 되었으나 명확한 비교를 위해 VanillaJS로 간단한 패턴 예제를 만들어 보았습니다.
MVC와 MVVM 모두 간단한 TODO List로 UI 상의 동작은 동일하고 View.js 파일 역시 동일합니다.
mvc와 mvvm 각 폴더를 보면 패턴을 가시화 하기 위해 최대한 패턴에서 쓰는 용어 그대로 클래스를 작성했습니다.
우선 가장 큰 차이인 Controller.js와 ViewModel.js 부터 보겠습니다.
Controller의 경우 Model이 업데이트될 때마다 해당 Model을 사용하는 View를 직접 업데이트를 해줘야합니다. 해당 Model을 사용하는 View가 많아질수록 Controller에 추가되는 코드 역시 증가합니다.
이에 비해 ViewModel의 경우 constructor에서 Model의 변경에 대한 View의 변경을 미리 바인딩 해둔 것을 볼 수 있습니다. 바인딩을 통해 Model의 변경을 자동으로 전파해주기에 ViewModel에서는 더 이상 Model의 변경에 따라 View를 직접 업데이트할 필요가 없어졌습니다. 해당 Model을 사용하는 View가 많아지거나 Model 쪽의 로직이 변경되어도 View에 직접적인 영향을 주지 않습니다.
그 다음으로 주목할 부분은 Observable.js 입니다.
Vanilla로 만든 간단한 Observable 패턴입니다. 해당 객체는 value와 callback을 갖고 있으며 setValue를 통한 변경 시 현재 유지되고 있는 callback 들이 실행되는 형태입니다. React에서 setState Hook과 비슷한 역할을 한다고 할 수 있습니다.
이를 상속 받아 만든 Model도 한번 보겠습니다.
todo를 추가하거나 삭제시 setValue를 통해 해당 객체가 가진 callback을 실행할 수 있게됩니다.
물론 여기서는 내부 동작 과정을 명확히 하기 위해 이를 구현하였으나 프레임워크에 따라 Observable 객체를 지원하는 케이스도 있고 Vue, Svelte 등은 해당 부분들이 프레임워크 내부에서 자동적으로 지원하기 때문에 이렇게 복잡하게 구현할 필요는 없습니다.
동작 원리를 보이기 위한 코드 정도로 봐주시면 좋을 것 같습니다.
마치며
패턴이라고 하는건 결국 개발에 대한 일종의 마인드셋이라고 할 수 있습니다. 특정 프레임워크가 특정 패턴을 기반으로 설계되었다고 해서 반드시 따라가야 하는 것이 아닙니다. 무엇을 사용하든 데이터를 보는 사고의 흐름이 튀지 않도록 패턴을 유지하는 것이 중요하다는 생각이 듭니다.
참고:
프론트엔드에서 MV* 아키텍쳐란 무엇인가요?
MVC, MVVM, MVI 아키텍쳐가 어쩌고 저쩌고... 소프트웨어를 공부하다 보면 한번쯤은 MV__로 시작되는 아키텍쳐라는 용어를 들어본적이 있을 겁니다. 실제로 프로그래밍을 할 때에는 중요하지 않아보
velog.io
https://medium.com/@bouab.nabil/javascript-intermediate-mvvm-vanilla-flavour-7f7cfbdf2da6
JavaScript Intermediate — MVVM vanilla flavour
“Fake it ‘till you make it” doesn’t work when developing in JavaScript. If you want to use any framework in JavaScript, you have to…
medium.com
https://pozafly.github.io/javascript/javascript-mvc/
JavaScript MVC 패턴으로 만드는 SPA
모던 JavaScript 프레임워크 없이 MVC 패턴으로 SPA을 만들어보자
pozafly.github.io
반응형'Web Programming' 카테고리의 다른 글
Git Versioning 및 CHANGELOG.md 생성 자동화 (0) 2023.01.30 Promise 객체 병렬처리 (0) 2022.09.29 Z-Index (0) 2022.08.24 Multi-Tenancy의 개념 (0) 2022.06.27 재고 - 주문 프로세스에서의 동시성 제어 (0) 2022.01.26