MVC, MVVM 그리고 Flux

.DS_Store·2025년 2월 16일
0

FrontEnd

목록 보기
27/27
post-thumbnail

본 포스팅은 ChatGPT를 통해 작성되었으며 일부 재구성되었습니다.

MVC패턴과 MVVM패턴의 차이

둘 다 UI 아키텍처 패턴이지만, 컨트롤러(Controller)와 뷰모델(ViewModel)의 역할이 다르고, 데이터 흐름 방식이 다름.

MVC (Model-View-Controller) 패턴

구조
Model: 데이터 및 비즈니스 로직을 처리하는 부분
View: 사용자 인터페이스(UI)를 담당
Controller: 사용자 입력을 받아 Model을 변경하고, View를 업데이트하는 역할

동작 방식
사용자가 View에서 입력을 수행
Controller가 입력을 받아서 Model을 변경
Model이 변경되면, View에 반영

MVC의 특징
Controller가 중심이 되어 View와 Model을 연결
View와 Model이 직접 연결될 수 있음 → 데이터 흐름이 완전히 단방향이 아님
주로 서버 사이드 웹 개발(Spring, ASP.NET 등)에 많이 사용

MVC 예시 (jQuery)

class Model {
  constructor() {
    this.count = 0;
  }
  
  increment() {
    this.count++;
  }
}

class View {
  constructor() {
    this.button = document.getElementById('button');
    this.display = document.getElementById('display');
  }
  
  render(count) {
    this.display.textContent = count;
  }
}

class Controller {
  constructor(model, view) {
    this.model = model;
    this.view = view;
    
    this.view.button.addEventListener('click', () => {
      this.model.increment();
      this.view.render(this.model.count);
    });
    
    this.view.render(this.model.count);
  }
}

const app = new Controller(new Model(), new View());

MVVM (Model-View-ViewModel) 패턴

구조
Model: 데이터 및 비즈니스 로직을 담당 (MVC와 동일)
View: UI를 담당 (MVC와 동일)
ViewModel: View와 Model 사이에서 데이터를 변환하여 바인딩하는 역할

동작 방식
사용자가 View에서 입력 수행
ViewModel이 입력을 받아 Model을 변경
ViewModel이 Model의 변경 사항을 자동으로 View에 반영

MVVM의 특징
ViewModel이 중심이 되어 View와 Model을 연결
데이터 바인딩(Two-Way Binding)을 지원 → ViewModel이 변경되면 자동으로 View가 업데이트됨
React, Vue, Angular 등 프론트엔드 프레임워크에서 많이 사용됨

MVVM 예제 (Vue3)

// View 역할
<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">+</button>
  </div>
</template>

<script setup>
import { ref } from "vue";

// 상태 (Model 역할)
const count = ref(0);

// 상태 변경 함수 (ViewModel 역할)
const increment = () => {
  count.value++;
};
</script>

MVC vs MVVM 비교

구분MVC (Model-View-Controller)MVVM (Model-View-ViewModel)
중심 요소ControllerViewModel
데이터 바인딩수동으로 UI 업데이트자동 데이터 바인딩 (Two-Way Binding 가능)
의존성 방향View ↔ Controller ↔ ModelView ↔ ViewModel ↔ Model
유지보수UI 변경 시 Controller 수정 필요UI 변경 시 ViewModel만 조정
적용 분야서버 사이드 웹 개발(Spring, Django 등)프론트엔드 개발(Vue, Angular 등)
코드 예측 가능성여러 요소가 직접 데이터를 변경 가능데이터 흐름이 더 직관적

Controller vs ViewModel: 가장 큰 차이점

구분Controller (MVC)ViewModel (MVVM)
역할View에서 요청을 받아 Model을 조작하고, 변경된 데이터를 View에 반영Model의 데이터를 가공하여 View에 바인딩하고, View의 변경을 Model에 자동 반영
데이터 바인딩수동 (View에서 데이터를 변경하면 Controller에서 이를 받아서 Model을 업데이트하고 다시 View를 갱신해야 함)자동 (View와 Model 간의 양방향 데이터 바인딩이 가능)
상태 관리Controller는 자체적으로 상태를 가지지 않음 (일반적으로 요청이 들어올 때만 실행됨)ViewModel은 상태를 가지며 지속적으로 View와 Model을 동기화
의존 관계View와 Controller는 서로를 알고 있음 (강한 결합)View와 ViewModel은 느슨한 결합 (ViewModel은 View를 모름)

예제 코드
📌 MVC 예제 (Controller가 View와 Model을 연결하는 방식)

// Model
class Model {
  constructor() {
    this.count = 0;
  }

  increment() {
    this.count++;
  }
}

// View
class View {
  constructor() {
    this.button = document.getElementById('button');
    this.display = document.getElementById('display');
  }

  render(count) {
    this.display.textContent = count;
  }
}

// Controller
class Controller {
  constructor(model, view) {
    this.model = model;
    this.view = view;

    // 버튼 클릭 시 Controller가 Model을 업데이트
    this.view.button.addEventListener('click', () => {
      this.model.increment();
      this.view.render(this.model.count);
    });

    this.view.render(this.model.count);
  }
}

const app = new Controller(new Model(), new View());

✅ Controller가 View와 Model을 연결하는데, 데이터 바인딩이 자동이 아니므로 render()를 직접 호출해야 한다.
✅ View는 Model을 직접 참조하지 않고 Controller를 통해 데이터를 가져온다.

MVVM 예제 (ViewModel이 자동으로 View와 Model을 동기화하는 방식 - React)

// ViewModel 역할 (useState가 Model과 View를 자동으로 동기화)
function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  );
}

✅ ViewModel(React의 useState)이 Model을 관리하며, View와 자동으로 동기화된다.
✅ View가 Model을 직접 참조하지 않고, setCount로 상태를 변경하면 자동으로 UI가 업데이트된다.
✅ 별도의 Controller 없이도 상태 변경이 UI에 즉시 반영된다.

React에 대해 공부하다보면 나오는 플럭스 패턴,
그럼 플럭스 패턴은 MVVM 패턴의 일부인걸까? 라는 의문이 생겼다.

플럭스(Flux) 패턴은 MVVM의 일부일까?

아니다! 플럭스(Flux)와 MVVM은 별개의 패턴이지만, 둘 다 UI 상태 관리를 위한 구조를 제공한다.
다만, MVVM이 플럭스보다 더 일반적인 개념이라서 일부 MVVM 패턴 기반의 프레임워크(예: Vue, Angular)에서도 플럭스와 유사한 데이터 흐름을 적용할 수 있다.

MVVM과 플럭스의 차이

구분MVVM (Model-View-ViewModel)Flux (Action-Dispatcher-Store-View)
데이터 흐름양방향 (Two-Way Binding 지원 가능)단방향 (One-Way Data Flow)
상태 변경 방식ViewModel에서 직접 Model을 업데이트Action → Dispatcher → Store를 거쳐 상태 변경
사용 목적UI 컴포넌트와 데이터를 연결하는 구조복잡한 상태 관리를 위한 구조
대표적인 예Vue, Angular, Knockout.jsReact + Redux

MVVM과 플럭스의 핵심 차이점

MVVM은 ViewModel이 상태를 직접 관리하고 View와 양방향 바인딩 가능
ViewModel이 UI 상태를 관리하며, View와 자동으로 동기화됨

MVVM vs. 플럭스 예제 코드

📌 MVVM 예제 (Vue.js)

<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">+</button>
  </div>
</template>

<script>
export default {
  data() {
    return { count: 0 };
  },
  methods: {
    increment() {
      this.count++;
    }
  }
}
</script>

✅ ViewModel(data() + methods)이 View와 Model을 연결하고, 상태가 변경되면 자동으로 UI가 업데이트됨.
양방향 데이터 바인딩(v-model)이 가능하여 ViewModel과 View가 실시간으로 동기화됨.

📌 플럭스 예제 (React + Redux)

// actions.js
export const INCREMENT = "INCREMENT";
export const increment = () => ({ type: INCREMENT });

// reducer.js
const initialState = { count: 0 };
export function counterReducer(state = initialState, action) {
  switch (action.type) {
    case INCREMENT:
      return { count: state.count + 1 };
    default:
      return state;
  }
}

// Counter.js
import { useSelector, useDispatch } from "react-redux";
import { increment } from "./actions";

function Counter() {
  const count = useSelector((state) => state.count);
  const dispatch = useDispatch();

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => dispatch(increment())}>+</button>
    </div>
  );
}

✅ 상태 변경이 Action → Reducer → Store → View 순서로 이루어짐 (단방향 데이터 흐름).
✅ View가 Store의 상태를 직접 변경할 수 없으며, 반드시 Action을 통해 상태 변경이 이루어짐.

0개의 댓글

관련 채용 정보