MVC Pattern vs. MVVC Pattern vs. MVP Pattern

MVC, MVP, MVVM 아키텍처 패턴은 모두 관심사 분리(SoC) 원칙에 기반하며, 각기 다른 방식으로 UI 로직과 비즈니스 로직을 분리한다.

MVC (Model-View-Controller)

▫ 구조

구성 요소역할
Model데이터 저장/비즈니스 로직 처리
ViewUI 표시 (사용자 입력 수신)
Controller입력 처리 → Model 업데이트 → View 갱신
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# Model: 데이터와 비즈니스 로직
class UserModel:
    def get_user_data(self):
        return {"name": "홍길동", "age": 30}

# View: 사용자 인터페이스
class UserView:
    def show_user(self, user_data):
        print(f"사용자 정보: {user_data}")

# Controller: Model과 View 사이의 중재자
class UserController:
    def __init__(self, model, view):
        self.model = model
        self.view = view
    
    def display_user(self):
        user = self.model.get_user_data()
        self.view.show_user(user)

▫ 데이터 흐름

1
2
사용자 → View → Controller → Model  
Model → Controller → View
  • 특징: View가 Model 직접 참조 가능
  • 장점: 구조 단순, 학습 곡선 낮음
  • 단점: View-Model 강결합 → 대규모 프로젝트 시 복잡성 증가

▫ 사용 사례

  • 웹 프레임워크(Spring MVC, Ruby on Rails)
  • 간단한 데스크톱 애플리케이션

MVP (Model-View-Presenter)

▫ 구조

구성 요소역할
Model데이터 및 비즈니스 로직
ViewUI 표시 (수동적, Presenter에 이벤트 전달)
PresenterView-Model 중재, UI 로직 처리
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Model: 데이터와 비즈니스 로직
class UserModel:
    def get_user_data(self):
        return {"name": "홍길동", "age": 30}

# View: 사용자 인터페이스와 이벤트 처리
class UserView:
    def __init__(self, presenter):
        self.presenter = presenter
    
    def show_user(self, user_data):
        print(f"사용자 정보: {user_data}")

# Presenter: View와 Model 사이의 중재자
class UserPresenter:
    def __init__(self, view, model):
        self.view = view
        self.model = model
    
    def load_user(self):
        user = self.model.get_user_data()
        self.view.show_user(user)

▫ 데이터 흐름

1
2
사용자 → View → Presenter ↔ Model  
Model → Presenter → View
  • 특징: View-Model 완전 분리
  • 장점: 테스트 용이성 ↑ (Presenter 단독 테스트 가능)
  • 단점: View-Presenter 1:1 관계 → 코드량 증가

▫ 사용 사례

  • Windows Forms, Android 앱
  • 복잡한 UI 로직이 필요한 프로젝트

MVVM (Model-View-ViewModel)

▫ 구조

구성 요소역할
Model데이터 소스 관리
ViewUI 및 데이터 바인딩
ViewModelView 상태 추상화, 데이터 변환
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Model: 데이터와 비즈니스 로직
class UserModel:
    def get_user_data(self):
        return {"name": "홍길동", "age": 30}

# ViewModel: View를 위한 Model의 데이터 변환과 상태 관리
class UserViewModel:
    def __init__(self, model):
        self.model = model
        self.user_data = None
        
    def fetch_user(self):
        self.user_data = self.model.get_user_data()
        # 데이터 바인딩을 통해 View가 자동으로 업데이트됨

# View: 사용자 인터페이스
class UserView:
    def __init__(self, view_model):
        self.view_model = view_model
        # 데이터 바인딩 설정

▫ 데이터 흐름

1
2
사용자 → View → ViewModel ↔ Model  
Model → ViewModel → View (자동 갱신)
  • 특징: 데이터 바인딩으로 자동 동기화
  • 장점: 재사용성 ↑, 양방향 데이터 흐름
  • 단점: 초기 설정 복잡, 과도한 추상화 가능성

▫ 사용 사례

  • WPF, Angular, React, Vue.js
  • 실시간 데이터 업데이트 필요 애플리케이션

패턴 비교

특성MVCMVVMMVP
데이터 흐름Controller → Model ↔ ViewViewModel ↔ Model, View ↔ ViewModelPresenter → Model, View ↔ Presenter
View와 Model의 관계직접 참조 가능완전 분리완전 분리
중간 계층의 역할Controller가 입력 처리ViewModel이 상태와 데이터 변환 관리Presenter가 View 상태와 이벤트 처리
테스트 용이성보통좋음매우 좋음
코드 복잡도낮음높음중간
주요 사용처웹 애플리케이션데스크톱/모바일 앱복잡한 UI 애플리케이션
데이터 바인딩수동자동수동
UI 의존성높음낮음매우 낮음

패턴 선택 가이드

  • MVC: 빠른 프로토타이핑, 간단한 웹 앱
  • MVP: Android 앱, UI 테스트 강조 환경
  • MVVM: 복잡한 데이터 플로우, 재사용성 요구 시

참고 및 출처