MVC 패턴과 Flux 패턴: 차이점과 이해
웹 개발 초기단계에서 효율적인 애플리케이션 구조를 설계하는 것은 매우 중요한 일이다. 이러한 구조를 정의하는데 있어서 MVC(Model-View-Controller) 패턴과 Flux 패턴은 널리 사용되는 설계 패턴이다. 이 글에서는 두 패턴의 개념, 차이점, 그리고 사용 사례를 비교하여 쉽게 이해할 수 있도록 설명해 보겠다.
MVC 패턴이란?
MVC는 애플리케이션을 세 가지 역할로 나누는 설계 패턴으로, Model, View, Controller로 구성된다. 역할을 분리하여 코드의 재사용성과 유지보수성을 높이는 데 중점을 둔다.
1. Model(모델)
애플리케이션의 데이터와 비즈니스 로직을 관리. 데이터베이스와 상호작용하여 데이터를 가져오거나 저장하고, 비즈니스 규칙을 적용한다. View나 Controller에 데이터를 제공한다.
2. View(뷰)
사용자가 보는 UI를 담당한다. Controller로부터 전달받은 데이터를 화면에 렌더링한다. HTML, CSS, JavaScript로 구현되며, 데이터 표시가 주된 역할이다.
3. Controller(컨트롤러)
Model과 View 사이를 연결하는 중계 역할을 한다. 사용자의 요청(ex. 버튼 클릭)을 처리하고, 적절한 Model을 호출하거나, View를 갱신한다.
MVC의 동작 흐름을 살펴보면 다음과 같다. 먼저 사용자가 입력(ex. URL 요청)을 전송하면, Controller가 요청을 처리하고 필요한 데이터를 Model에서 가져온다. View는 Controller로부터 데이터를 받아 사용자에게 출력한다. MVC 패턴을 사용하는 데 있어 장단점이 존재하는데, 역할 분리가 명확해 유지보수가 쉽고 코드 재사용성이 높다는 장점이 있지만 복잡한 애플리케이션에서는 데이터 흐름이 복잡해질 수 있다.
Flux 패턴이란?
Flux는 Facebook이 React 애플리케이션을 위해 설계한 아키텍쳐. 패턴이다. Flux는 단방향 데이터 흐름(Unidirectional Data Flow)을 중심으로 상태(state)관리를 단순화한다. Flux의 구성 요소에는 네 가지가 있는데, 조금 더 자세히 살펴보면 아래와 같다.
1. Action
상태 변경의 의도를 나타낸다. 예를 들어, 사용자가 버튼을 클릭하면 "ADD_TODO"라는 Action이 생성된다.
const addTodoAction = {
type: 'ADD_TODO',
payload: { text: 'Learn Flux' }
};
2. Dispatcher
Action을 Store로 전달하는 중앙 허브 역할을 한다. 등록된 Store에 Action을 브로드캐스트 한다.
dispatcher.dispatch(addTodoAction);
3. Store
애플리케이션의 상태를 저장하고 관리한다. Dispatcher로부터 전달받은 Action을 처리하여 상태를 변경하고, View에 변경 사실을 알린다.
class TodoStore {
constructor() {
this.todos = [];
}
handleAction(action) {
if (action.type === 'ADD_TODO') {
this.todos.push(action.payload.text);
this.emitChange();
}
}
emitChange() {
// View에 상태 변경 알림
}
}
4. View
Store에서 상태를 구독하여 UI를 업데이트한다. React 컴포넌트로 구현되는 경우가 많다.
const TodoView = () => {
const todos = TodoStore.getTodos();
return (
<ul>
{todos.map((todo, index) => (
<li key={index}>{todo}</li>
))}
</ul>
);
};
Flux의 동작 흐름은 1~4 순서로, 사용자가 입력(ex. 버튼 클릭)을 통해 Action을 생성하면, Dispatcher가 Action을 Store에 전달하고, Store는 상태를 변경하고 View에 알린다. 그러면 마지막으로 View는 새로운 상태를 렌더링한다. Flux 패턴도 역시 장단점이 존재하는데, 단방향 데이터 흐름으로 인해 데이터 변경의 추적과 디버깅이 쉽다는 장점이 존재하지만, 구성 요소가 많아 초기 학습이 어려울 수 있다는 단점이 있다.