[Design Pattern] MVC && MVVM
MVC 패턴(Moder-View-Controller) 패턴
MVC 패턴은 하나의 애플리케이션의 역할을 Model, View, Controller로 구분한다. 개발 시, 각 구성 요소가 독립된 역할을 수행하므로 코드를 작성할 때, “이 로직을 어디에다 두어야 하지?”하는 고민을 해결할 수 있다.

3가지 역할
Model
어플리케이션의 데이터와 비즈니스 로직을 관리한다. DB와 소통하거나, 데이터를 가공을 담당하고 있다. 뷰에서 input box, check box 등 UI요소를 통해서 데이터가 생성되거나 갱신되는 경우, 컨트롤러를 통해서 이벤트를 통지받고, 모델을 갱신한다.
View
모델을 데이터를 받아서 시각적으로 출력한다. 즉, 사용자가 볼 수 있는 화면을 뜻한다. input box, check box, text area등 단순히 화면에 표시하는 정보만 가지고 있다. 또한 변경이 일어나면, 컨트롤러에게 변경을 알려야 한다. 여기서 말하는 변경은 앞서 언급한 체크박스가 체크가 되거나, text area 에 텍스트가 생성되는 경우를 말한다.
Controller
하나 이상의 모델과 하나 이상의 뷰를 잇는 다리 역할을 한다. 모델이나 뷰의 변경 통지를 받으면 이를 해석해서 각각의 구성요소에 해당 내용을 알려준다.
3가지 요소가 소통하는 과정 예시(좋아요 버튼)
View → Controller : 사용자가 좋아요 버튼을 누른다.
Controller → Model : 컨트롤러가 클릭 이벤트를 감지하고 모델에게 “좋아요 숫자가 1 증가”를 명령한다.
Model → Controller : DB를 갱신하고, 상태가 변했음을 컨트롤러에 알린다.
Controller → View : View는 Model의 데이터를 기반으로 UI를 업데이트 한다.
React
MVC 패턴을 차용하는 대표적인 라이브러리는 UI를 구축하는 React이다. 가상 DOM을 만들어 실제 DOM의 조작을 추상화하여 성능을 높인 것이 특징이다.
| 구분 | React 요소 | 역할 |
|---|---|---|
| Model | State & Props | 데이터의 상태를 말한다. 예를 들어 setState를 통해서만 수정할 수 있다. |
| Controller | Event Handler & Hooks | 사용자의 입력을 받아 state를 변경한다. onClick과 같은 이벤트 리스너들이 컨트롤러 역할을 한다. |
| View | Virtual DOM | 화면에 무엇을 그릴지 정의한다. |
React 렌더링 프로세스
React는 모델(State)이 변경되었을 때 곧바로 실제 화면을 그리지 않는다.
- 가상 DOM 업데이트: 상태 변경 시 가상 DOM을 먼저 업데이트한다.
- Diffing : 이전 가상 DOM과 현재의 가상 DOM을 비교하여 차이점을 찾아낸다.
- 최종적으로 변경된 부분만 실제 DOM에 반영하여 리렌더링한다.
사실 React는 양방향 흐름을 가지는 MVC패턴보다는 MVVM패턴에 더 가깝다. 가상 DOM을 통해서 상태 변화를 감지하고 자동으로 뷰를 동기화해주는 흐름을 가지고 있기에 MVVM의 데이터 바인딩과 매우 흡사하기 때문이다.
MVVM 패턴

MVVM 패턴은 Controller 대신 모델과 뷰를 중계하는 ViewModel을 사용한다. ViewModel의 상태가 변하면 연결된 View가 자동으로 업데이트되는 ‘데이터 바인딩’이 핵심인데, React에서는 가상 DOM이 이 바인딩 과정을 효율적으로 처리해 준다.
코드 구현
우리가 작성하는 React 컴포넌트는 그 자체로 하나의 MVVM 단위를 이룬다.
1
2
3
4
5
6
7
8
9
10
11
12
13
import { counterViewModel } from "./Example"
const view = () => {
const [count, increase] = counterViewModel();
return(
<article>
<h1>{count}</h1>
<button onClick={increase}>UP</button>
</article>
)
}
위의 코드에서 우리가 document.getElementById.innerText = … 와 같이 직접 DOM에 접근하지 않고도 count를 사용해서 사용자에게 어떻게 보여줄지 정의할 수 있다.
장점
의존성 감소: UI 수정은 View에서, 데이터 가공은 ViewModel에서 독립적으로 관리할 수 있다.
테스트 용이: 데이터 가공 로직만 분리된 ViewModel은 UI 없이도 단위 테스트(Unit Test)를 진행하기 수월하다.
재사용성 향상: 검증된 ViewModel은 서로 다른 여러 컴포넌트에서 재사용할 수 있다.
마치며
디자인 패턴은 정답이 아닌, 협업과 유지보수를 위한 약속이다. 우리가 사용하는 기술 스택이 어떤 패턴을 지향하는지 이해한다면 더욱 견고하고 깔끔한 코드를 설계할 수 있을 것이다.