일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 비동기
- named type
- react animation
- Swift
- rn
- promise.all
- react-native
- Promise
- animation
- react-native-image-picker
- React-Native업데이트
- RN아키텍쳐
- react
- async
- Hash-table
- private-access-to-photos
- react-native-permissions
- CS
- react native
- Throttle
- debounce
- hydration mismatch
- axios
- no-permission-handler-detected
- RN새로운아키텍쳐
- javascript
- await
- ios
- motion.div
- RN업데이트
- Today
- Total
하루살이 개발일지
프론트엔드 아키텍처 패턴의 진화 본문
프론트엔드 개발의 역사는 단순히 UI를 구성하는 수준을 넘어서며, 점점 더 복잡하고 체계적인 상태 관리와 아키텍처의 필요성을 만들어냈다. 특히 2010년대 초반, 자바스크립트의 역동성이 증가하면서 기존 서버 중심의 렌더링 방식에서 벗어나 클라이언트 사이드 애플리케이션의 필요성이 대두되었다. 이에 따라 자바스크립트를 좀 더 구조적으로 활용하기 위한 시도로 MVC, MVVM 같은 디자인 패턴이 대두되었으며, Backbone.js, AngularJS 등이 그 대표 주자였다.
이후 React가 등장하며 기존 양방향 바인딩 구조의 복잡성을 해결하고자 하였고, Flux 패턴이라는 단방향 데이터 흐름 기반 구조가 탄생하였다. 현재는 React 중심으로 컴포넌트 기반 아키텍처와 다양한 상태 관리 도구가 결합된 구조로 진화하고 있다.
이 글에서는 프론트엔드 아키텍처 패턴의 진화를 자바스크립트 기반 웹 개발의 역사적 흐름과 함께 정리하고, React 중심의 현재 트렌드까지 포괄적으로 설명하고자 한다.
1. 초기 웹 개발과 MVC 패턴의 도입
초기의 웹 개발은 서버에서 HTML을 생성하여 클라이언트에 전달하는 방식이 일반적이었다. 자바스크립트는 단순한 폼 유효성 검사나 DOM 조작을 위한 부가적인 역할에 머물렀다. 그러나 웹 앱의 복잡도가 증가하면서 클라이언트에서 더 많은 로직을 수행할 필요성이 생기고, 이에 따라 구조적인 자바스크립트 앱을 만들기 위한 시도가 시작되었다.
MVC 패턴은 이 시점에서 각광받기 시작한 구조적 접근 방식으로, 다음과 같이 구성된다:
Model | 데이터와 비즈니스 로직을 담당 |
View | 사용자에게 보여지는 UI 요소를 담당 |
Controller | 사용자 입력을 처리하고, Model과 View를 연결 |
Model: 애플리케이션의 핵심 데이터와 비즈니스 로직을 담당한다. 예를 들어 사용자가 작성한 메모, 로그인 상태, 서버로부터 받은 API 데이터 등이 모두 Model에 해당된다. Model은 데이터의 생성, 수정, 삭제, 검색 등을 수행하며, View나 Controller에 대한 정보를 직접 갖지 않아야 한다.
View: 사용자에게 보여지는 화면(UI)을 담당한다. HTML, CSS, DOM 요소들로 구성되어 있으며, Model로부터 데이터를 받아 이를 화면에 렌더링하는 역할을 한다. View는 사용자로부터 받은 입력을 Controller에게 전달하며, Model의 상태에 따라 갱신된다.
Controller: 사용자 입력을 받아서 처리하고, 그에 따라 Model을 조작하거나 View를 갱신하는 로직을 담당한다. 예를 들어 사용자가 버튼을 클릭하면 Controller가 이 이벤트를 받아서 Model을 업데이트하고, 그 결과를 View에 반영하는 식이다.
데이터 흐름
사용자 입력 → Controller → Model 업데이트 → View 갱신
MVC의 바인딩은 수동 또는 단방향이다. 즉, Model의 변화가 자동으로 View에 반영되지는 않으며, View에서 Model로의 데이터 전달 역시 명시적으로 컨트롤러를 통해 이루어진다.
대표 사례: Backbone.js
아래 코드는 Backbone.js에서 Model과 View를 사용하는 간단한 예제이다. Todo 모델은 할 일 항목을 나타내며, title과 completed라는 두 개의 속성을 가진다. TodoView는 사용자의 클릭 이벤트를 처리하고, 해당 모델의 completed 값을 반전시킨다. 여기서 toggleCompleted 함수가 Controller의 역할을 수행하며, Model을 직접 업데이트한다. 즉, 사용자가 .toggle 클래스가 붙은 UI 요소를 클릭하면, Model의 completed 속성이 반전되며 View에 변화가 반영된다.
var Todo = Backbone.Model.extend({
defaults: {
title: '',
completed: false
}
});
var TodoView = Backbone.View.extend({
events: {
'click .toggle': 'toggleCompleted'
},
toggleCompleted: function() {
this.model.set('completed', !this.model.get('completed'));
}
});
MVC의 현재
MVC는 서버 중심의 웹 개발과 초기 자바스크립트 구조화에 기여했지만, 클라이언트 로직이 많아질수록 Controller의 역할이 불분명해지고 데이터 흐름이 복잡해지는 단점이 나타났다. 현재는 프론트엔드보다는 Ruby on Rails, Django, Spring 같은 백엔드 프레임워크에서 더 널리 사용된다.
2. MVVM 패턴과 AngularJS의 등장
MVC의 한계를 보완하고자 등장한 MVVM 패턴은 View와 Model의 동기화를 자동화하는 구조로, 특히 AngularJS를 통해 널리 확산되었다.
Model | 데이터 및 비즈니스 로직을 담당 |
View | 사용자 인터페이스(UI)를 담당 |
ViewModel | View와 Model 사이를 연결하며, 양방향 바인딩을 통해 데이터 변화를 자동 반영 |
Model: 사용자 인터페이스에서 사용되는 핵심 데이터를 담고 있다. 예를 들어 입력 폼의 값, 리스트의 항목들, 사용자 이름과 같은 정보가 이에 해당한다. Model은 뷰나 다른 구성요소에 대한 의존 없이 데이터 처리에만 집중해야 하며, 외부 변경 사항에 대해 이벤트 기반으로 반응할 수 있어야 한다.
View: 텍스트 입력창, 체크박스, 버튼 등 사용자가 직접 조작하는 요소들로 구성된다. View는 데이터 자체를 저장하지 않고 단지 모델의 데이터를 받아 시각적으로 표현하며, 사용자의 입력을 ViewModel로 전달하는 역할을 한다.
ViewModel: View와 Model 사이의 중간자 역할을 하며, 양방향 바인딩을 통해 View의 입력을 실시간으로 Model에 반영하고, 반대로 Model의 변경도 View에 자동으로 반영되도록 한다. 비즈니스 로직은 최소한으로 유지하며, View의 상태를 관리하는 데 집중한다.
데이터 흐름
View ↔ ViewModel ↔ Model
대표 사례: AngularJS
아래 코드는 AngularJS에서 양방향 바인딩을 사용하는 예시로, 사용자가 <input> 필드에 이름을 입력하면 user.name 속성이 자동으로 업데이트되고, 동시에 {{ user.name }} 텍스트도 자동으로 갱신된다. $scope.user는 ViewModel의 역할을 수행한다.
<input type="text" ng-model="user.name">
<p>Hello {{ user.name }}!</p>
$scope.user = { name: 'Haru' };
MVVM의 현재
MVVM은 초기에는 효율적인 UI 데이터 바인딩 방식으로 각광받았지만, 프로젝트 규모가 커질수록 데이터 흐름을 추적하기 어려운 문제가 발생했다. 현재는 Angular(2+)에서도 MVVM보다는 명시적 데이터 흐름과 단방향 바인딩이 강조되고 있으며, React의 영향으로 복잡한 양방향 바인딩 구조는 점차 줄어드는 추세다.
3. React와 Flux의 등장
React의 등장 배경
React는 2013년 Facebook에서 등장했다. 초기에는 단순히 View 계층만 담당하는 라이브러리로 시작되었지만, 기존 양방향 바인딩 방식의 복잡성을 피하고 선언형 UI를 통해 명확한 상태 관리를 가능하게 했다.
Flux의 필요성과 구조
React는 View만 담당했기 때문에 상태 관리에 대한 새로운 구조가 필요했다. 이를 해결하기 위해 등장한 Flux는 다음과 같은 단방향 데이터 흐름 구조를 가진다:
Action | 사용자 상호작용이나 외부 이벤트 등으로 발생하는 신호 |
Dispatcher | 액션을 중앙에서 받아 스토어로 전달하는 역할 |
Store | 실제 상태를 보관하며, 비즈니스 로직도 일부 포함 |
View | Store에서 상태를 받아와 렌더링하는 React 컴포넌트 |
Flux 데이터 흐름
사용자 → Action → Dispatcher → Store → View → 사용자
이 구조는 상태가 한 방향으로만 흐르기 때문에, 상태의 변화를 추적하고 예측하기 용이하다. 이후 Redux, Recoil, Zustand 등 다양한 상태 관리 도구가 Flux 철학을 계승하며 발전하였다.
4. 아키텍처 패턴 비교 정리
항목 | MVC | MVVM | Flux (React 중심) |
중간 역할 | Controller | ViewModel | Dispatcher + Store |
바인딩 | 수동 또는 단방향 | 양방향 바인딩 | 단방향 데이터 흐름 |
대표 사례 | Backbone.js | AngularJS | React + Flux/Redux |
구조 복잡성 | 중간 | 양방향 관리가 어려움 | 초기 학습 곡선 있으나 예측 가능 |
5. 현대 React 생태계의 흐름
오늘날 프론트엔드 개발은 다음과 같은 방향으로 발전하고 있다:
- 단방향 데이터 흐름 유지: React의 핵심 철학으로, 상태 추적이 쉽다.
- 컴포넌트 중심 구조: 로직과 UI를 독립된 단위로 관리하며 재사용성과 유지보수성을 높인다.
- Hook 기반 상태 관리: useState, useReducer, useContext를 이용한 컴포넌트 내부 상태 관리가 일반화되었다.
- 전용 상태 관리 도구: Redux, Recoil, Zustand, Jotai 등 외부 상태 관리를 위한 도구들이 활용되고 있다.
- 서버 상태 관리의 발전: React Query, SWR을 통한 API 캐싱, 로딩/에러 핸들링 등 서버 상태도 체계적으로 관리된다.
6. 결론
프론트엔드 아키텍처는 웹 기술의 발전과 함께 끊임없이 진화해왔다. 초기의 서버 중심 렌더링에서 MVC 기반의 구조화된 자바스크립트로, 다시 AngularJS의 MVVM 구조를 거쳐, React와 Flux의 단방향 흐름 중심 구조로 이어진 변화는 단순한 코드 설계 방식을 넘어서 사용자 경험과 유지보수성까지 영향을 끼친다.
React는 단방향 흐름과 선언형 UI, 컴포넌트 중심 구조를 통해 프론트엔드 개발의 기준을 새롭게 정의했다. 현대 개발자에게는 이러한 흐름을 이해하고 적절한 상태 관리 도구와 구조를 선택하는 능력이 요구된다. 이는 단순한 기술의 습득이 아닌, 복잡한 애플리케이션을 효과적으로 설계하고 협업할 수 있는 기반이 된다.
'웹개발' 카테고리의 다른 글
npm install -E의 의미에 대하여 (0) | 2023.09.17 |
---|