Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 198 additions & 0 deletions 챕터_8/백지연.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
# CHAPTER 08 자바스크립트 MV\* 패턴

애플리케이션 설계의 두 가지 중요한 측면

- 객체의 설계 (앞에서 살펴본 패턴)
- 애플리케이션 아키텍처 ([MVC](#1-mvc-패턴), [MVP](#2-mvp-패턴), [MVVM](#3-mvvm-패턴))

## 1. MVC 패턴

Model-View-Controller

**관심사의 분리**를 활용하는 아키텍처 디자인 패턴

- Model = 비즈니스 데이터
- View = UI
- Controller = 로직과 사용자 입력

### Smalltalk-80의 MVC 패턴

#### 목표

'분리된 프레젠테이션' 개념을 발전시켜 애플리케이션 로직과 UI 분리

#### 설계의 기본 개념

애플리케이션의 일부를 분리함으로써 모델을 애플리케이션의 다른 인터페이스에도 재사용

#### 특징

관찰자 패턴이 포함되어 있음
Smalltalk-80의 MVC에서 뷰는 모델을 관찰해 모델(= 도메인 데이터)이 바뀔 때마다 뷰가 반응함
ex. 주식 시장 데이터 기반 애플리케이션

### 자바스크립트의 MVC

3가지 핵심 요소로 구성

#### 모델

- 애플리케이션 **데이터**를 관리하는 역할
- 모델이 변경될 때 관찰자에게 변경사항을 알림
- 갤러리 애플리케이션에서는 '사진'이 모델이며, 모델에는 '설명, 이미지 소스, 추가 메타데이터' 같은 속성이 포함될 수 있음
- 모델을 컬렉션으로 그룹화하는 기능을 제공하는 경우가 많음 (개별 모델 인스턴스를 직접 관찰할 필요가 없어짐)

#### 뷰

- 모델에 대한 **시각적인 표현**으로, **현재 상태**의 특정 부분만 보여줌

- Smalltalk의 뷰는 비트맵을 생성하고 관리하는 역할
- JavaScript의 뷰는 여러 DOM 요소의 집합을 생성하고 정리하는 역할

- **모델을 관찰**하고, 모델에 변화가 생기면 알림을 받아 스스로 업데이트

- 모델/컨트롤러에 대한 정보를 제한적으로 갖기 때문에 뷰를 둔하다(dumb)고도 함

- 사용자는 뷰와 상호작용
- 갤러리 애플리케이션의 경우 사진의 메타데이터를 편집할 수 있는 '편집 뷰'를 제공해 모델 편집을 용이하게 함
- 실제 업데이트는 컨트롤러가 담당

#### 템플릿

- 뷰와 연관
- 뷰 객체의 일부 또는 전체를 선언적으로 지정하는 방법이 될 수 있음
- 뷰를 생성하기 위해 템플릿이 사용될 수 있음
- **tagged template literals** 같은 최신 템플릿 기법을 통해 동적인 HTML 콘텐츠를 만들 수 있음

> styled-components, emotion에서 잘 쓰고 있던 개념이네요😮
> https://styled-components.com/docs/advanced#tagged-template-literals
> https://emotion.sh/docs/css-prop#string-styles
> https://youtube.com/shorts/zaIWtaQle3o?si=D9_GzgolXgicxb7w

> 또 다른 활용 사례 (이스케이프 문자)
> https://youtube.com/shorts/w-aeIlS1Qc8?si=D2YxgKARa4cTozfP
> https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/raw
> `String.raw()` 메서드는 템플릿 리터럴의 태그 함수
> 템플릿 리터럴의 윈시 문자열을 가져오는 예시

```javascript
const filePath = 'C:\Development\profile\aboutme.html';
console.log(`The file was uploaded from: ${filePath}`);
// output: "The file was uploaded from: C:Developmentprofileaboutme.html"
```

```javascript
const filePath = String.raw`C:\Development\profile\aboutme.html`;
console.log(`The file was uploaded from: ${filePath}`);
// output: "The file was uploaded from: C:\Development\profile\aboutme.html"
```

#### 컨트롤러

- 모델과 뷰 사이의 **중재자** 역할
- 사용자가 뷰를 조작할 때 모델을 업데이트
- 사용자 입력에 뷰가 응답할 수 있도록 컨트롤러가 지원하는 것은 **전략 패턴**의 예시이기도 함

### MVC를 사용하는 이유는?

관심사 분리는 기능을 더 간단한 모듈로 나눌 수 있도록 해주며, 다음과 같은 이점 제공

- 유지보수의 단순화 : 변경사항이 데이터 중심인지, 단순히 시각적 변경인지 명확하게 구분 가능
- 모델과 뷰의 분리 : 비즈니스 로직에 대한 단위 테스트를 작성하기 좋음
- 코드 중복 제거
- 모듈화를 통해 코어 로직을 담당하는 개발자와 UI를 담당하는 개발자가 동시에 작업 가능

### MVC의 또 다른 관점

GoF는 MVC를 디자인 패턴으로 언급하지 않고 **UI를 구축하기 위한 클래스의 집합**으로 간주
GoF의 관점에서 MVC는 **관찰자, 전략, 컴포지트 패턴**의 변형
프레임워크에서 구현된 방식에 따라 **팩토리, 템플릿 패턴**도 사용될 수 있음

## 2. MVP 패턴

Model-View-Presenter

### 모델, 뷰, 프리젠터

뷰에 대한 UI 비즈니스 로직을 담당하는 구성 요소가 프리젠터
MVC와 달리 뷰에서의 이벤트 호출은 프리젠터로 위임
복잡한 로직을 프리젠터 안에 캡슐화할 수 있어 유지보수에 좋음

#### 장점

높은 테스트 용이성, 뷰와 모델 간의 명확한 분리

#### 단점

데이터 바인딩이 지원되지 않기 때문에 작업을 별도로 처리해야 하는 비용 발생

### MVP vs MVC

MVP 패턴이 적합한 경우

- 프레젠테이션 로직을 최대한 재사용해야 하는 엔터프라이즈 수준의 애플리케이션
- 뷰가 매우 복잡하고 사용자와의 상호작용이 많은 애플리케이션

## 3. MVVM 패턴

Model-View-ViewModel

MVC와 MVP를 기반으로 하는 패턴
UI 개발 부분과 비즈니스 로직, 동작 부분을 명확하게 분리
선언적 데이터 바인딩을 활용해 뷰에 대한 작업을 다른 계층과 분리
→ 동일한 코드베이스에서 UI 작업과 개발 작업 거의 동시에 진행 가능

### 모델

다른 패턴들과 마찬가지로 도메인 관련 데이터나 정보 제공
동작을 다루지 않으며, 정보 형식을 지정하지 않고, 데이터가 브라우저에 어떻게 표현될지에 영향을 미치지 않음
데이터 형식 지정은 뷰가 담당하고, 동작은 뷰모델에서 캡슐화하여 처리해야 하는 비즈니스 로직으로 간주

모델의 역할 중 유일한 예외는 **데이터 유효성 검사**
ex. 입력된 이메일 주소가 정규식을 충족하는지 모델에서 유효성 검사 수행하는 것 허용

### 뷰

- 수동적 뷰 : 단순히 화면을 출력할 뿐 사용자의 입력을 받아들이지 않음
- 능동적 뷰 : 데이터 바인딩, 이벤트, 동작들을 포함하고 있어 뷰모델에 대한 이해를 필요로 함

### 뷰모델

데이터 변환기의 역할을 하는 특수한 컨트롤러

- 모델의 정보를 뷰가 사용할 수 있는 형태로 변환
- 뷰에서 발생한 명령(사용자 조작이나 이벤트)을 모델로 전달

UI 계층의 뒤에 뷰모델이 위치함
뷰모델은 뷰보다 **모델에 더 가깝지만 뷰의 디스플레이 로직 대부분을 처리**
뷰와 뷰모델은 데이터 바인딩과 이벤트를 통해 소통

뷰모델은 모델에 대해 전적인 책임을 지고 있음
데이터 바인딩을 위해 모델 또는 모델의 속성을 가져올 수 있음
뷰에 제공되는 속성을 가져오거나 조작하기 위한 인터페이스를 포함할 수 있음

### 장점

- UI와 이를 구동하는 요소를 동시에 개발 가능
- 뷰를 추상화함으로써 뷰의 뒤에 작성되는 비즈니스 로직의 양을 줄여줌
- 뷰모델은 이벤트 중심 코드에 비해 단위 테스트가 쉬움
- 뷰모델은 뷰보다 모델에 가깝기 때문에 UI 자동화나 상호작용에 대한 고려 없이도 테스트 가능

### 단점

- 단순한 UI의 경우 MVVM은 과도한 구현
- 데이터 바인딩은 선언적이고 사용하기 편리하지만, 단순히 breakpoint를 설정하는 명령형 코드에 비해 디버깅이 어려움
- 복잡한 애플리케이션에서는 데이터 바인딩 관리 부담이 커지고, 바인딩 대상 객체보다 바인딩 코드가 무거운 상황이 생길 수 있음
- 대규모 애플리케이션에서는 미리 뷰모델을 설계하기 어려움

## MVC vs MVP vs MVVM

모두 MVC에서 파생된 패턴
각 계층이 다른 계층에 대해 갖는 의존성, 계층이 서로 연결된 정도가 다름

## MV\* 패턴과 리액트

리액트는 MVC 프레임워크가 아님
기존 MVC처럼 중앙 제어 역할을 하는 컨트롤러 혹은 라우터 기능이 포함되어 있지 않음
리액트에서는 서버가 브라우저에 '뷰'를 직접 제공하지 않고, '데이터'를 제공함
리액트와 마찬가지로 Next.js도 MVC 프레임워크는 아니지만, SSR 또는 SSG를 사용하는 경우 MVC와 유사하게 동작
Loading