|
| 1 | +# CHAPTER 08 자바스크립트 MV\* 패턴 |
| 2 | + |
| 3 | +애플리케이션 설계의 두 가지 중요한 측면 |
| 4 | + |
| 5 | +- 객체의 설계 (앞에서 살펴본 패턴) |
| 6 | +- 애플리케이션 아키텍처 ([MVC](#1-mvc-패턴), [MVP](#2-mvp-패턴), [MVVM](#3-mvvm-패턴)) |
| 7 | + |
| 8 | +## 1. MVC 패턴 |
| 9 | + |
| 10 | +Model-View-Controller |
| 11 | + |
| 12 | +**관심사의 분리**를 활용하는 아키텍처 디자인 패턴 |
| 13 | + |
| 14 | +- Model = 비즈니스 데이터 |
| 15 | +- View = UI |
| 16 | +- Controller = 로직과 사용자 입력 |
| 17 | + |
| 18 | +### Smalltalk-80의 MVC 패턴 |
| 19 | + |
| 20 | +#### 목표 |
| 21 | + |
| 22 | +'분리된 프레젠테이션' 개념을 발전시켜 애플리케이션 로직과 UI 분리 |
| 23 | + |
| 24 | +#### 설계의 기본 개념 |
| 25 | + |
| 26 | +애플리케이션의 일부를 분리함으로써 모델을 애플리케이션의 다른 인터페이스에도 재사용 |
| 27 | + |
| 28 | +#### 특징 |
| 29 | + |
| 30 | +관찰자 패턴이 포함되어 있음 |
| 31 | +Smalltalk-80의 MVC에서 뷰는 모델을 관찰해 모델(= 도메인 데이터)이 바뀔 때마다 뷰가 반응함 |
| 32 | +ex. 주식 시장 데이터 기반 애플리케이션 |
| 33 | + |
| 34 | +### 자바스크립트의 MVC |
| 35 | + |
| 36 | +3가지 핵심 요소로 구성 |
| 37 | + |
| 38 | +#### 모델 |
| 39 | + |
| 40 | +- 애플리케이션 **데이터**를 관리하는 역할 |
| 41 | +- 모델이 변경될 때 관찰자에게 변경사항을 알림 |
| 42 | +- 갤러리 애플리케이션에서는 '사진'이 모델이며, 모델에는 '설명, 이미지 소스, 추가 메타데이터' 같은 속성이 포함될 수 있음 |
| 43 | +- 모델을 컬렉션으로 그룹화하는 기능을 제공하는 경우가 많음 (개별 모델 인스턴스를 직접 관찰할 필요가 없어짐) |
| 44 | + |
| 45 | +#### 뷰 |
| 46 | + |
| 47 | +- 모델에 대한 **시각적인 표현**으로, **현재 상태**의 특정 부분만 보여줌 |
| 48 | + |
| 49 | + - Smalltalk의 뷰는 비트맵을 생성하고 관리하는 역할 |
| 50 | + - JavaScript의 뷰는 여러 DOM 요소의 집합을 생성하고 정리하는 역할 |
| 51 | + |
| 52 | +- **모델을 관찰**하고, 모델에 변화가 생기면 알림을 받아 스스로 업데이트 |
| 53 | + |
| 54 | + - 모델/컨트롤러에 대한 정보를 제한적으로 갖기 때문에 뷰를 둔하다(dumb)고도 함 |
| 55 | + |
| 56 | +- 사용자는 뷰와 상호작용 |
| 57 | + - 갤러리 애플리케이션의 경우 사진의 메타데이터를 편집할 수 있는 '편집 뷰'를 제공해 모델 편집을 용이하게 함 |
| 58 | + - 실제 업데이트는 컨트롤러가 담당 |
| 59 | + |
| 60 | +#### 템플릿 |
| 61 | + |
| 62 | +- 뷰와 연관 |
| 63 | +- 뷰 객체의 일부 또는 전체를 선언적으로 지정하는 방법이 될 수 있음 |
| 64 | +- 뷰를 생성하기 위해 템플릿이 사용될 수 있음 |
| 65 | +- **tagged template literals** 같은 최신 템플릿 기법을 통해 동적인 HTML 콘텐츠를 만들 수 있음 |
| 66 | + |
| 67 | + > styled-components, emotion에서 잘 쓰고 있던 개념이네요😮 |
| 68 | + > https://styled-components.com/docs/advanced#tagged-template-literals |
| 69 | + > https://emotion.sh/docs/css-prop#string-styles |
| 70 | + > https://youtube.com/shorts/zaIWtaQle3o?si=D9_GzgolXgicxb7w |
| 71 | +
|
| 72 | + > 또 다른 활용 사례 (이스케이프 문자) |
| 73 | + > https://youtube.com/shorts/w-aeIlS1Qc8?si=D2YxgKARa4cTozfP |
| 74 | + > https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/raw |
| 75 | + > `String.raw()` 메서드는 템플릿 리터럴의 태그 함수 |
| 76 | + > 템플릿 리터럴의 윈시 문자열을 가져오는 예시 |
| 77 | +
|
| 78 | + ```javascript |
| 79 | + const filePath = 'C:\Development\profile\aboutme.html'; |
| 80 | + console.log(`The file was uploaded from: ${filePath}`); |
| 81 | + // output: "The file was uploaded from: C:Developmentprofileaboutme.html" |
| 82 | + ``` |
| 83 | + |
| 84 | + ```javascript |
| 85 | + const filePath = String.raw`C:\Development\profile\aboutme.html`; |
| 86 | + console.log(`The file was uploaded from: ${filePath}`); |
| 87 | + // output: "The file was uploaded from: C:\Development\profile\aboutme.html" |
| 88 | + ``` |
| 89 | + |
| 90 | +#### 컨트롤러 |
| 91 | + |
| 92 | +- 모델과 뷰 사이의 **중재자** 역할 |
| 93 | +- 사용자가 뷰를 조작할 때 모델을 업데이트 |
| 94 | +- 사용자 입력에 뷰가 응답할 수 있도록 컨트롤러가 지원하는 것은 **전략 패턴**의 예시이기도 함 |
| 95 | + |
| 96 | +### MVC를 사용하는 이유는? |
| 97 | + |
| 98 | +관심사 분리는 기능을 더 간단한 모듈로 나눌 수 있도록 해주며, 다음과 같은 이점 제공 |
| 99 | + |
| 100 | +- 유지보수의 단순화 : 변경사항이 데이터 중심인지, 단순히 시각적 변경인지 명확하게 구분 가능 |
| 101 | +- 모델과 뷰의 분리 : 비즈니스 로직에 대한 단위 테스트를 작성하기 좋음 |
| 102 | +- 코드 중복 제거 |
| 103 | +- 모듈화를 통해 코어 로직을 담당하는 개발자와 UI를 담당하는 개발자가 동시에 작업 가능 |
| 104 | + |
| 105 | +### MVC의 또 다른 관점 |
| 106 | + |
| 107 | +GoF는 MVC를 디자인 패턴으로 언급하지 않고 **UI를 구축하기 위한 클래스의 집합**으로 간주 |
| 108 | +GoF의 관점에서 MVC는 **관찰자, 전략, 컴포지트 패턴**의 변형 |
| 109 | +프레임워크에서 구현된 방식에 따라 **팩토리, 템플릿 패턴**도 사용될 수 있음 |
| 110 | + |
| 111 | +## 2. MVP 패턴 |
| 112 | + |
| 113 | +Model-View-Presenter |
| 114 | + |
| 115 | +### 모델, 뷰, 프리젠터 |
| 116 | + |
| 117 | +뷰에 대한 UI 비즈니스 로직을 담당하는 구성 요소가 프리젠터 |
| 118 | +MVC와 달리 뷰에서의 이벤트 호출은 프리젠터로 위임 |
| 119 | +복잡한 로직을 프리젠터 안에 캡슐화할 수 있어 유지보수에 좋음 |
| 120 | + |
| 121 | +#### 장점 |
| 122 | + |
| 123 | +높은 테스트 용이성, 뷰와 모델 간의 명확한 분리 |
| 124 | + |
| 125 | +#### 단점 |
| 126 | + |
| 127 | +데이터 바인딩이 지원되지 않기 때문에 작업을 별도로 처리해야 하는 비용 발생 |
| 128 | + |
| 129 | +### MVP vs MVC |
| 130 | + |
| 131 | +MVP 패턴이 적합한 경우 |
| 132 | + |
| 133 | +- 프레젠테이션 로직을 최대한 재사용해야 하는 엔터프라이즈 수준의 애플리케이션 |
| 134 | +- 뷰가 매우 복잡하고 사용자와의 상호작용이 많은 애플리케이션 |
| 135 | + |
| 136 | +## 3. MVVM 패턴 |
| 137 | + |
| 138 | +Model-View-ViewModel |
| 139 | + |
| 140 | +MVC와 MVP를 기반으로 하는 패턴 |
| 141 | +UI 개발 부분과 비즈니스 로직, 동작 부분을 명확하게 분리 |
| 142 | +선언적 데이터 바인딩을 활용해 뷰에 대한 작업을 다른 계층과 분리 |
| 143 | +→ 동일한 코드베이스에서 UI 작업과 개발 작업 거의 동시에 진행 가능 |
| 144 | + |
| 145 | +### 모델 |
| 146 | + |
| 147 | +다른 패턴들과 마찬가지로 도메인 관련 데이터나 정보 제공 |
| 148 | +동작을 다루지 않으며, 정보 형식을 지정하지 않고, 데이터가 브라우저에 어떻게 표현될지에 영향을 미치지 않음 |
| 149 | +데이터 형식 지정은 뷰가 담당하고, 동작은 뷰모델에서 캡슐화하여 처리해야 하는 비즈니스 로직으로 간주 |
| 150 | + |
| 151 | +모델의 역할 중 유일한 예외는 **데이터 유효성 검사** |
| 152 | +ex. 입력된 이메일 주소가 정규식을 충족하는지 모델에서 유효성 검사 수행하는 것 허용 |
| 153 | + |
| 154 | +### 뷰 |
| 155 | + |
| 156 | +- 수동적 뷰 : 단순히 화면을 출력할 뿐 사용자의 입력을 받아들이지 않음 |
| 157 | +- 능동적 뷰 : 데이터 바인딩, 이벤트, 동작들을 포함하고 있어 뷰모델에 대한 이해를 필요로 함 |
| 158 | + |
| 159 | +### 뷰모델 |
| 160 | + |
| 161 | +데이터 변환기의 역할을 하는 특수한 컨트롤러 |
| 162 | + |
| 163 | +- 모델의 정보를 뷰가 사용할 수 있는 형태로 변환 |
| 164 | +- 뷰에서 발생한 명령(사용자 조작이나 이벤트)을 모델로 전달 |
| 165 | + |
| 166 | +UI 계층의 뒤에 뷰모델이 위치함 |
| 167 | +뷰모델은 뷰보다 **모델에 더 가깝지만 뷰의 디스플레이 로직 대부분을 처리** |
| 168 | +뷰와 뷰모델은 데이터 바인딩과 이벤트를 통해 소통 |
| 169 | + |
| 170 | +뷰모델은 모델에 대해 전적인 책임을 지고 있음 |
| 171 | +데이터 바인딩을 위해 모델 또는 모델의 속성을 가져올 수 있음 |
| 172 | +뷰에 제공되는 속성을 가져오거나 조작하기 위한 인터페이스를 포함할 수 있음 |
| 173 | + |
| 174 | +### 장점 |
| 175 | + |
| 176 | +- UI와 이를 구동하는 요소를 동시에 개발 가능 |
| 177 | +- 뷰를 추상화함으로써 뷰의 뒤에 작성되는 비즈니스 로직의 양을 줄여줌 |
| 178 | +- 뷰모델은 이벤트 중심 코드에 비해 단위 테스트가 쉬움 |
| 179 | +- 뷰모델은 뷰보다 모델에 가깝기 때문에 UI 자동화나 상호작용에 대한 고려 없이도 테스트 가능 |
| 180 | + |
| 181 | +### 단점 |
| 182 | + |
| 183 | +- 단순한 UI의 경우 MVVM은 과도한 구현 |
| 184 | +- 데이터 바인딩은 선언적이고 사용하기 편리하지만, 단순히 breakpoint를 설정하는 명령형 코드에 비해 디버깅이 어려움 |
| 185 | +- 복잡한 애플리케이션에서는 데이터 바인딩 관리 부담이 커지고, 바인딩 대상 객체보다 바인딩 코드가 무거운 상황이 생길 수 있음 |
| 186 | +- 대규모 애플리케이션에서는 미리 뷰모델을 설계하기 어려움 |
| 187 | + |
| 188 | +## MVC vs MVP vs MVVM |
| 189 | + |
| 190 | +모두 MVC에서 파생된 패턴 |
| 191 | +각 계층이 다른 계층에 대해 갖는 의존성, 계층이 서로 연결된 정도가 다름 |
| 192 | + |
| 193 | +## MV\* 패턴과 리액트 |
| 194 | + |
| 195 | +리액트는 MVC 프레임워크가 아님 |
| 196 | +기존 MVC처럼 중앙 제어 역할을 하는 컨트롤러 혹은 라우터 기능이 포함되어 있지 않음 |
| 197 | +리액트에서는 서버가 브라우저에 '뷰'를 직접 제공하지 않고, '데이터'를 제공함 |
| 198 | +리액트와 마찬가지로 Next.js도 MVC 프레임워크는 아니지만, SSR 또는 SSG를 사용하는 경우 MVC와 유사하게 동작 |
0 commit comments