**모델-뷰-뷰 모델**(model-view-viewmodel, MVVM)은 하나의 소프트웨어 아키텍처 패턴으로-마크업 언어 또는 GUI 코드로 구현하는-그래픽 사용자 인터페이스(뷰)의 개발을 비즈니스 로직 또는  백-엔드 로직(모델)로부터 분리시켜서 뷰가 어느 특정한 모델 플랫폼에 종속되지 않도록 해준다. MVVM의 뷰 모델은 값 변환기인데, 이는 뷰 모델이 모델에 있는 데이터 객체를 노출(변환)하는 책임을 지기 때문에 객체를 관리하고 표현하기가 쉬워진다는 것을 의미한다. 이러한 점에서, 뷰 모델은 뷰 보다는 더 모델인 것이며, 모든 뷰들의 디스플레이 로직을 제외한 대부분의 것들을 처리한다. 뷰 모델은 '백-엔드 로직에 대한 접근'과 그 주변부의 '뷰에서 지원하는 유즈 케이스 집합'으로 구성되도록, 중재자 패턴으로 구현할 수도 있다.

MVVM은 마틴 파울러(Martin Fowler)의 '프레젠테이션 모델 디자인 패턴' 의 변형이다. 이는 사용자 인터페이스의 이벤트-기반 프로그래밍을 단순화하기 위해 마이크로소프트의 아키텍트인 켄 쿠퍼(Ken Cooper)와 테드 피터스(Ted Peters)에 의해 발명되었다. 이 패턴은 (마이크로소프트의 닷넷 그래픽 시스템인) 윈도우 프레젠테이션 파운데이션 (WPF) 및 (WPF의 인터넷 응용 프로그램 파생품인) 실버라이트에 통합되었다. 마이크로소프트의 WPF 와 실버라이트 아키텍트인, 존 구스먼(John Gossman)은 2005년 자신의 블로그에 MVVM을 발표하였다.

모델-뷰-뷰모델은 **모델-뷰-바인더**(model-view-binder)라고도 하는데, 특히 닷넷 플랫폼과 상관없이 구현된 경우를 지칭한다. (자바로 작성된 웹 프레임워크인) ZK와 (자바스크립트 라이브러리인) KnockoutJS는 모델-뷰-바인더를 사용한다.

MVVM 패턴의 구성 요소
--------------

모델 (Model)
모델은 실제 상태 내용을 표현하는, 도메인 모델을 참조하거나 (이는 객체-지향 접근법이라 한다), 또는 내용을 표현하는, 데이터 접근 계층을 참조한다. (이는 데이터-중심 접근법이라 한다).
뷰 (View)
모델-뷰-컨트롤러(MVC)와 모델-뷰-프리젠터(MVP) 패턴에서와 같이, 뷰는 사용자가 화면에서 보는 것들에 대한 구조, 배치, 그리고 외관에 해당한다. 모델을 보여서 표현하고 사용자와 뷰의 상호 작용(클릭, 키보드, 동작 등)을 수신하여, 이에 대한 처리를 뷰와 뷰 모델의 연결을 정의하고 있는 (속성, 이벤트 콜백 함수 등의) 데이터 바인딩(data binding, 데이터 연결)을 통하여 뷰 모델로 전달한다.
뷰 모델 (View Model)
뷰 모델은 공용 속성과 공용 명령을 노출하는 뷰에 대한 추상화(abstraction)이다. MVC 패턴의 컨트롤러나, MVP 패턴의 프리젠터(presenter, 발표자)를 대신하여, MVVM은 바인더(binder, 연결자)를 가지고 있는데, 이는 뷰 모델에 있는 뷰에 연결된 속성과 뷰 사이의 통신을 자동화 한다. 뷰 모델은 모델에 있는 데이터의 상태라고 설명했었다.
뷰 모델과 MVP 패턴에 있는 프리젠터 사이의 주요한 차이점은 프리젠터는 뷰에 대한 참조를 가지고 있는 반면, 뷰 모델은 그렇지 않다는 것이다. 그 대신, 뷰는 뷰 모델의 속성에 직접 '연결된(binds)' 채로 업데이트를 주고 받는다. 효율적으로 작동하려면, '바인딩 기술(binding technology, 연결 기술)' 또는 '바인딩'을 하는  상용구 코드 (boilerplate code)의 자동 생성이 필수이다.
바인더 (Binder, 연결자)
MVVM 패턴에서는 선언적인 데이터와 '명령-바인딩(명령-연결)'이 내재되어 있다. 마이크로소프트 솔루션 스택에서, 바인더는 XAML이라는 마크업 언어이다. 바인더는 뷰 모델과 뷰의 동기화를 위해 상용구 로직을 작성해야 하는 의무에서 개발자를 해방시켜 준다. 마이크로소프트 스택을 사용하지 않고 구현한다면, '선언적인 데이터 바인딩 기술' 이 있어야 이 패턴을 만들 수 있으며, 바인더가 없다면, 그 대신 일반적인 MVP 나 MVC를 사용해야 할 것이고 더 많은 상용구 코드를 작성하게 (아니면 이를 다른 도구로 생성하게) 될 것이다.

근거
--

MVVM은 뷰 계층에서 사실상 모든 GUI 코드를 제거하여, 뷰 계층의 개발을 패턴 나머지 부분에서 더 용이하게 분리하기 위해 WPF(윈도 프리젠테이션 파운데이션)의 데이터 바인딩 기능을 사용하도록 설계되어 있다. 사용자 경험(UX) 개발자는 GUI 코드를 직접 작성하는 대신, (XAML 같은) 프레임워크의 마크업 언어를 사용하여 뷰 모델에 대한 데이터 바인딩(연결)을 생성할 수 있으며, 이 뷰 모델은 응용 프로그램 개발자가 작성하고 관리하게 된다. 이러한 역할의 분리는 상호 작용 설계자가 비지니스 로직의 프로그래밍 보다는 UX 의 요구에 집중할 수 있도록 해준다. 그로 인해 응용 프로그램 계층별로 개발 흐름을 여러 개로 나누어서 생산성을 높일 수 있다. 설령 단일 개발자가 전체 코드 기반의 작업을 하게 되는 경우라 하더라도, 모델과 뷰를 적절히 분리하는 것이 더 생산적인데, 사용자 인터페이스는 일반적으로 최종-사용자의 피드백에 따라 개발 주기 과정에서 자주 그리고 뒤늦게 바뀌기 때문이다.

MVVM 패턴은 데이터를 가능한 순수한 응용 프로그램 모델에 가깝게 바인딩(연결)하는 데이터 바인딩과 프레임워크의 장점을 활용함과 동시에, MVC가 제공하는 기능 요소 개발의 분리라는 장점까지 해서, 이 둘을 다 얻으려고 시도한다. 이는 바인더(연결자), 뷰 모델, 그리고 어떤 비즈니스 계층에든 있는 데이터-검사 기능을 사용하여 들어오는 데이터를 검증한다. 결과적으로 모델과 프레임워크가 가능한 많은 작업을 수행하며, 뷰를 직접 조작하는 응용 프로그램 로직은 최소화하거나 아예 없애버린다.

비판
--

이 패턴에 대한 비판은 MVVM 제작자인 존 구스만(John Gossman) 자신이 한 것인데, 단순한 UI 작업에서는 MVVM을 구현하는 부담이 "지나치게 과하다" 고 지적한다. 그가 말하길 응용 프로그램이 점점 더 커짐에 따라서, 뷰 모델을 폭 넓게 사용하기가 점점 더 어려워진다고 한다. 게다가 아주 큰 응용 프로그램에서 데이터 바인딩을 사용하게 되면 눈에 띄게 메모리를 소모하게 된다고 설명한다.

구현체
---

### 닷넷 프레임워크

* Prism Library
* Caliburn / Caliburn.Micro
* DevExpress MVVM
* DotVVM open source project
* MVVMLight Toolkit
* ReactiveUI
* Mugen MVVM Toolkit
* Uno Framework - Open Source
* Rascl
* MvvmCross

### 자바스크립트 프레임워크

* 앵귤러
* 리액트 (자바스크립트 라이브러리)
* Aurelia
* Durandal
* Ember.js
* Ext JS
* Knockout.js
* Omi.js
* Oracle JET
* Svelte
* Vue.js