MVC? MVVM? in frontend

이현우·2024년 1월 19일
1

1. 이야기에 앞서

경험: 과제테스트에서 지시 사항과 테스트와 객체지향 디자인 원칙에 집중해주십시오.
라는 문구가 등장했다. (UI가 필요한 프로그램이 아닌 console에서 동작하는 프로그램을 작성하도록 요구한다.)

문득, 주어진 개발 환경에 따라 어떤 디자인 패턴을 사용하면 좋을지 궁금해졌다.

어떤 디자인 패턴을?

다음 3가지의 경우, 어떤 디자인 패턴을 쓰는 것이 적합한지 알아보고자 한다.
1. cli programming in vanila javascript 과제가 주어졌을 때
2. event driven programming in vanila javascript 과제가 주어졌을 때
3. react(component driven development, event driven programming) 과제가 주어졌을 때

2. 디자인 패턴

소프트웨어 개발 방법에서 사용되는 디자인 패턴은 프로그램 개발에서 자주 나타나는 과제를 해결하기 위한 방법 중 하나로, 과거의 소프트웨어 개발 과정에서 발견된 설계의 노하우를 축적하여 이름을 붙여, 이후에 재이용하기 좋은 형태로 특정의 규약을 묶어서 정리한 것이다. 알고리즘과 같이 프로그램 코드로 바로 변환될 수 있는 형태는 아니지만, 특정한 상황에서 구조적인 문제를 해결하는 방식을 설명해 준다.
위키백과 - 소프트웨어 디자인 패턴

3. MVC 패턴

View

UI에서 가장 중요한 것은 역시 화면이죠.
첫번째는 우리가 제일 쉽게 이해할 수 있는 부분! 바로 이 View입니다.
웹 프론트에서는 대개 최종적으로 HTML과 CSS로 만들어지는 결과물을 의미합니다.

Model

소프트웨어가 멈춰있는 화면만 있으면 디자인과 다를 게 없겠죠.
화면에의 어딘가는 실제의 데이터가 반영이 되어 나타나야 합니다.
이러한 데이터를 주관하는 영역을 Model이라고 부릅니다.

javascript의 Object일 수도 있고,
서버의 API로 받는 데이터일수도 있고,
서버에 있는 DB일 수도 있습니다.

어쨌든 화면이 아닌 소프트웨어가 다뤄야할 중요한 데이터 영역입니다.

Controller

UI 소프트웨어의 본질은 단순합니다. 우선 데이터를 화면에 그립니다. 그리고 우리가 어떤 동작을 취하면 데이터가 바뀝니다. 데이터가 바뀌면 다시 화면이 바뀌겠죠.

이렇게 Model의 데이터를 받아서 화면에 그리고, 화면으로 부터 사용자의 동작을 받아서 Model을 변경합니다. 이러한 Model과 View사이의 중간 역할을 하는 것을 Controller라고 합니다.

MVC가 이렇게 나눠진 이유는,

화면을 다루는 문제와 데이터를 다루는 문제의 성격이 달라서 분리하고 싶고
Model과 View간의 의존관계를 최소화 해서 화면의 수정이 데이터수정에 영향을 미치지 않고 데이터 수정이 화면의 수정에 영향을 미치지 않고자 함입니다.

3-1. 초창기 MVC 패턴

웹 프론트엔드라는 개념도 없던 웹 서비스 초창기 시절의 MVC는

데이터베이스를 Model로 취급하고
HTML과 CSS, 그리고 javascript까지 포함한 클라이언트 영역을 View로
그리고 가운데서 라우터를 통해 데이터를 처리하고 새로운 HTML을 만들어서 보여주는 백엔드 영역을 Controller라고 취급했습니다.

3-2. jQuery시절의 MVC 아키텍쳐

그러다가 프론트엔드의 역할이 추가되고 특히 ajax라는 기술이 만들어지면서 이제는 HTML을 서버에서 직접 만들 필요가 없게 되었습니다.

이때부터는 웹 프론트엔드의 MVC의 개념이 조금씩 바뀌게 됩니다

ajax로 부터 받는 데이터를 Model로 취급합니다.
HTML과 CSS로 만들어지는 화면을 View로 취급합니다.
javascript가 중간에서 서버의 데이터를 받아서 화면을 바꾸고 이벤트를 처리해서 서버에 데이터를 전달하는 Controller의 역할을 수행하게 됩니다.
기존의 서버 라우터에서 하던 어떤 역할들이 이제 클라이언트의 자바스크립트가 처리하게 되었고 Database는 백엔드의 역할이며 REST API의 ajax 데이터가 Model이 됩니다.

이 시절 Controller의 가장 주요한 역할을 했던 게 바로 jQuery입니다. 그래서 이 개념을 이해하시고 다시 jQuery를 들여다 보면 jQuery에서 가장 핵심이 되는 기술이

  • DOM Traversal and Manipulation
  • Event Handling
  • Ajax

였다는 것을 알 수 있습니다.

이 당시 가장 중요한 패러다임은 관점의 분리로서 Model과 View의 종속성을 최대한 분리하는 해야한다는 원칙으로 HTML과 jQuery를 따로 관리하는 것이 주효했습니다.

4. MVVM 패턴

그 다음 나온 아키텍처가 바로 MVVM이라는 아키텍처입니다.

jQuery로 작업을 하다보니 상당히 불편한 점을 발견하게 됩니다. 데이터를 찾아서 데이터를 바꾸고 데이터를 수정하고 이벤트를 연결하고 이벤트를 수정하는 부분들에서 피곤한 반복적인 패턴이 나타난다는 것을 알게 되었습니다.

서버에서 개발을 할 때에는 html이 전체적으로 렌더링으로 되다보니 {{ }}, , <%= %> 와 같은 치환자로 통해 선언적으로 편하게 개발을 하는 반면 jQuery의 경우 전체 html를 갱신했다가는 번쩍거리는 화면을 맛볼 수 있으니 수정해야 할 부분을 일일히 찾아서 수정을 해줘야 했습니다.

클라이언트 개발도 서버처럼 템플릿과 같은 선언적인 방식

Model이 변하면 View를 수정하고 View에서 이벤트를 받아서 Model를 변경한다는 Controller의 역할은 그대로 인데 이를 구현하는 방식이 jQuery와 같은 DOM 조작에서 템플릿과 바인딩을 통한 선언적인 방법으로 변하게 됩니다.

이제는 코드에서 DOM을 조작하는 코드가 사라지고 이 기능들은 프레임워크가 담당하게 됩니다. 이제 개발자는 화면에 그려져야할 데이터만 만들어서 프레임워크에 전달해주면 프레임워크가 알아서 그려줍니다.

이를 View를 그리는 Model만 다루게 되었다는 의미로 ViewModel이라고 부르며 이 방식을 MVVM이라고 부르게 됩니다.

이후 나오는 프레임워크인 React, Vue, Angular2, Svelte등 어떤 방식의 템플릿과 바인딩 문법을 쓰느냐 방식만 다를 뿐 MVVM이라는 아키텍쳐는 그대로 유지되게 됩니다.

  • MVC에서 MVVM으로 오면서 달라진 부분
    컨트롤러의 반복적인 기능이 선언적인 방식으로 개선이 되었다.
    Model과 View의 관점을 분리하려 하지 않고 하나의 템플릿으로 관리하려는 방식으로 발전했다. (기존에는 class나 id등으로 간접적으로 HTML에 접근하려고 했다면 이제는 직접적으로 HTML에 접근하는 방법으로 확장이 되었다.)

MVVM을 얻은 웹 프론트엔드 개발은 그야말로 무시무시한 생산성의 변화를 맞이하게 됩니다. 웹의 DOM API를 잘 다루지 못하더라도 비지니스로직에만 집중한다면 금방 금방 서비스를 만들 수가 있게 되었습니다.


결론

그동안 frontend 프로그래밍을 하면서 객체지향을 겪어보지 못했을까?

경험상 component driven development, event driven programming에서는 프로토타입, class 기반 객체지향 둘 다 쓸일이 없었다.
굳이 class를 사용해본 것이라고는

  • error boundary 사용을 위한 class형 컴포넌트 사용
  • http통신시 statful한 class 객체 활용 in 횡단 관심사

독특한 상황 뿐이였다.

특히, React를 함수형 컴포넌트로 개발을 해왔기 때문에 클래스형 컴포넌트의 상태와 생명주기 객체지향을 제대로 겪지 못했다고 생각한다. 함수형 컴포넌트는 객체지향 프로그래밍보다는 함수형 프로그래밍에 가깝다고 한다.

다음 3가지 경우의 적합한 디자인 패턴 주관적 결론짓기

  1. cli programming in vanila javascript
  2. event driven programming in vanila javascript
  3. react(component driven development, event driven programming)
  1. cli-programming에서는 고전 mvc패턴을 선택할 것 같다.
    첫번째로는, 몇 안되게 알고있는 패턴중에 MVVM이 있는데 이것은 브라우저 환경이 기본적으로 갖쳐줘야 하기 때문에 소거된다. DOM을 기반으로 데이터를 전달하면 알아서 그려줄 ViewModel 의미를 갖춘 프레임워크이 존재할 수 없다.
    jQuery 시절의 MVC 패턴도 소거된다. 마찬가지로 브라우저 환경이 아니므로 서버와 클라이언트가 구분져있지 않기 때문에 HTTP통신 자체가 없으며, 특징적으로 자체적 model을 가지게 된다. 따라서 고전의 MVC패턴을 사용하도록 한다.
    모든 과제에 단정짓기는 어려우나 일반적으로, cli-programming에서 객체지향 디자인을 원칙을 함께 요구하기에, oop를 중요시하고 Model과 View간의 의존관계를 최소화하여 데이터수정에 영향을 미치지 않도록 mvc패턴을 적용시키도록 하려한다.
  1. 브라우저 환경에서 web2.0 ajax라는 기술이 존재하기 때문에 cli-programming에는 존재하지 않는 프론트엔드의 역할에 집중하도록 한다. (주로 todo-list나 타이머 과제)
  • Model: 서버의 DB는 REST API와 ajax HTTP 통신을 통해 접근한다.
  • View: DOM Traversal and Manipluation과 Event Handling이 중요하겠다.
  • Controller: 과거의 MVC에서 controller는 라우터의 역할 뿐이였지만, web2.0부터는 사용자로부터 event 감지하는 브라우저 역할이 controller라고 생각한다.
  1. react를 사용하면 DOM 조작을 하기 보다는, model을 수정하면 자동으로 view를 수정해주는 방식을 사용하는 ViewModel의 MVVM패턴을 사용하게 된다. 나아가 Page단위가 아닌 컴포넌트 단위인 Component 패턴을 사용하여 컴포넌트를 재사용하는 방식으로 프로그래밍을 진행할 것이다. Component 패턴에서 심화된 Container-Presenter 패턴을 사용하다 Props Driliing이 심하게 되어 필요시 FLUX패턴을 사용하게 될 것 같다.

참고

velog/@teo - 프론트엔드에서 MV* 아키텍쳐란 무엇인가요?

1개의 댓글

comment-user-thumbnail
2024년 1월 20일

평소에 프론트엔드의 디자인 패턴에 대해 별로 생각해본 적이 없었는데, 덕분에 어떤 식으로 흘러왔고 MVVM에 대해서도 더 잘 알수 있었습니다. 좋은 글 잘읽었습니다.

답글 달기