본문 바로가기
목차
CE

[Programming] MVC, MVVM, and Qt's MV

by ds31x 2025. 4. 14.
728x90
반응형

MVC Architecture (or Pattern)란?

MVC(Model-View-Controller)는 애플리케이션을 세 가지 주요 논리적 구성 요소인

  • 모델(Model),
  • 뷰(View),
  • 컨트롤러(Controller)

분리하는 아키텍처 패턴 .

 

비즈니스 로직과 UI를 분리 (or loosly coupling이 되도록)함으로써 코드의 유지보수성과 확장성을 높이는 것이 목적.

전통적으로 데스크톱 GUI에서 출발했지만, 웹과 모바일에서도 널리 여러 형태의 variation으로 사용되고 있음.


MVC의 구성 요소

  • Model:
    • 데이터 및
    • 비즈니스 로직 담당
    • 예: DB 연동, 데이터 처리
    • 데이터 소스를 추상화.
  • View:
    • 사용자에게 UI로 정보 제공
    • 예: 텍스트, 버튼, 폼
  • Controller:
    • View로부터 들어온 사용자 입력을 해석
    • 이를 통해 Model과 View를 제어

MVC의 동작 흐름

  1. 사용자가 View를 통해 입력함 (event 발생).
  2. View는 입력을 약속된 방식으로 Controller로 전달함.
  3. Controller는 입력을 해석하고 이에 따라 Model을 갱신하거나 View를 조작.
  4. Model이 변경되면 View가 이를 반영하여 UI를 갱신: Push 또는 Polling 이용하거나 Contorller가 개입하여 갱신

참고: Push vs Polling

  • Push: Model이 View에 알림 (예: 음식이 준비되었어요!)
  • Polling: View가 주기적으로 Model에 묻는 방식 (예: 음식 준비됐나요?)

MVC의 한계: Model-View 간 높은 결합도

MVC에서는 View가 Model의 내부 구조를 직접 참조하거나, Model이 View에 직접 알림을 보내는 구조를 취하는데
이는 다음과 같은 문제를 야기함:

  • 변경 전파 시 View도 함께 수정해야 함
  • 애플리케이션이 커질수록 복잡도와 유지보수 비용 증가
  • 테스트 자동화 어려움

MVVM(Model-View-ViewModel) 패턴

이러한 MVC의 결합도(coupling) 문제를 해결하기 위해 MVVM(Model-View-ViewModel) 패턴이 도입됨.

 

MVVM은 View와 Model 사이에 ViewModel이라는 중간 계층을 추가하여 다음과 같은 장점을 제공함:

  • View는 Model을 직접 참조하지 않고 ViewModel과만 상호작용
  • ViewModel은 View를 위한 데이터를 구성하고 명령(Command)을 처리
  • 데이터 바인딩 기술을 활용하여 UI 업데이트를 자동화

MVVM에서 Command란?

MVVM에서 Command는 사용자 입력(예: 버튼 클릭 등)을 ViewModel로 전달하는 메커니즘을 가리킴.

이는 MVC의 Controller가 담당하던 역할 중 사용자 입력 해석 및 처리 부분에 해당함.


Command의 구조와 동작

  1. View의 버튼 등 UI 요소에 Command가 바인딩됨
  2. 사용자가 버튼을 클릭하면 해당 Command 객체의 execute() 메서드가 호출됨
  3. ViewModel 내 로직이 실행되어 Model을 갱신하거나 데이터를 처리함
  4. Model의 변경이 ViewModel로 전달되고, 데이터 바인딩을 통해 View가 자동으로 갱신됨

예시 흐름 (Pseudo code로 개념만 이해할 것)

# ViewModel 예시
class OrderViewModel:
    def __init__(self):
        self.menu_items = ObservableList()
        self.order_command = Command(self.place_order)

    def place_order(self):
        Model.process_order()
        self.menu_items.value = Model.get_updated_menu()
<!-- View (예시) -->
<Button text="주문하기" command="{Binding order_command}" />

Qt에서의 대응 (PySide6 예시)

PySide6에서는 명시적인 Command 객체 대신 Slot 과 Signal을 활용:

class MyViewModel(QObject):
    @Slot()
    def place_order(self):
        # 주문 처리 로직
        ...

button.clicked.connect(view_model.place_order)

Command를 사용하면 View와 ViewModel 간의 결합도를 낮추면서도 깔끔한 입력 처리 구조를 만들 수 있음.


MVVM에서 MVC의 Controller는 어떻게 대체되었는가?

MVC의 Controller는 MVVM에서 명시적으로 존재하지 않으며, 그 기능 일부는 ViewModel이 대체함.

  • View로부터의 사용자 입력을 처리하는 기능: ViewModel의 Command 객체에 View의 UI요소(button등)을 바인딩하여 처리.
  • View에 데이터 변경 등을 적용: ViewModel과 binding을 통해 암묵적으로 처리됨.

하지만 Controller와 ViewModel은 완전히 동일한 역할은 아님..

구분 Contorller (MVC) ViewMode (MVVM)
목적 사용자 행동을 해석하여 Model 조작 View를 위한 데이터 및 로직 관리
UI 제어 직접 View를 조작하거나 호출 UI와 데이터 바인딩으로 자동 반영
테스트 용이성 UI 의존 높아 테스트 어려움 UI와 분리되어 단위 테스트 가능
동작 방식 명령 기반 호출 (imperative) 바인딩 기반 갱신 (declarative)

ViewModel은 View에 바인딩되는데 왜 독립적인 테스트 가능한 이유

이 질문에 대한 답은 바로
"바인딩은 View에서 ViewModel을 참조할 뿐, 그 반대는 아니기 때문" 임.

  • ViewModel은 UI 위젯 클래스나 이벤트 처리 코드를 포함하지 않음.
  • View가 ViewModel의 속성에 바인딩하거나 명령을 연결할 뿐임 (단방향 짝사랑).
  • ViewModel은 순수한 데이터/로직 객체이며, 단위 테스트에서도 UI 없이 독립적으로 테스트할 수 있음.

즉, ViewModel은 View의 존재를 몰라도 되고,
View가 ViewModel의 상태를 바인딩해 갱신될 뿐임.


Qt의 Model-View (MV) 아키텍처

Qt는 MVC를 보다 간소화한 Model-View(MV) 구조를 채택하고 있음.

때문에, Controller를 제거하거나 축소하여 Model과 View의 직접 연결 이 이루어짐: 실제로 View가 Controller의 역할 같이 수행.


구성 요소

  • Model: QAbstractItemModel 기반 데이터 소스
  • View: QListView, QTableView 등
  • Delegate (선택): View 내 표시 및 편집 커스터마이징하는 구성 요소 (MVC, MVVM에는 없는 요소)

동작 흐름

  1. Model이 데이터를 관리하고 제공.
  2. View가 UI로 데이터를 표시.
  3. 사용자의 입력은 View 또는 Delegate가 처리하고, Model을 직접 갱신.
  4. Model은 dataChanged 등의 신호(method호출)를 통해 View에 변경 사항을 통지.

MVC vs MVVM vs Qt MV 비교 요약

항목 MVC MVVM Qt's MV
중재자 Controller ViewModel 없음 (View가 직접 처리)
데이터 흐름 View → Controller → Model View ↔ ViewModel ↔ Model View ↔ Model
View와 Model 연결 명시적 메서드 호출 데이터 바인딩 Signal-Slot (주로)
테스트 용이성 낮음 높음 (ViewModel 독립성) 중간 (View 의존도 있음)
UI 분리 수준 중간 높음 낮음 (View가 구조를 알아야 함)

 


비유 정리 (식당 예시로 비교)

MVC

  • 고객(View)이 웨이터(Controller)에게 주문
  • 웨이터가 요리사(Model)에게 전달
  • 음식이 준비되면 요리사(Model)가 고객(View)에게 알려줌 (Push) 또는 고객이 물어봄 (Polling)

예시: 전통적인 레스토랑에서 종업원에게 주문하고 음식이 준비되었는지 기다리는 방식


MVVM

  • 각 고객(View)은 자신의 태블릿 메뉴판을 통해 주문
  • 태블릿은 ViewModel과 연결되어 있어 메뉴, 재고, 상태가 실시간 반영됨
  • 주문은 ViewModel을 통해 Model로 전달
  • Model의 변화는 ViewModel을 통해 자동 반영되어 태블릿 화면이 갱신됨

예시: 테이블에 설치된 키오스크 또는 태블릿에서 실시간으로 품절 메뉴가 표시되고 주문이 처리되는 시스템


Qt MV

  • 고객(View)이 메뉴판을 보고 직접 요리사(Model)에게 주문
  • 중간 웨이터(Controller)는 없음
  • 요리사가 준비 상태를 알리면 화면(View)이 자동으로 반응

예시: 셀프 서비스 식당에서 메뉴를 직접 보고 주문하며, 상태가 즉시 화면에 표시되는 구조

 


결론 요약

  • MVC는 Controller 중심 구조지만 View-Model 결합도가 높음
  • MVVM은 ViewModel 도입으로 View와 Model을 완전히 분리하며, ViewModel은 UI와 분리되어 테스트 가능하고 재사용 가능한 독립 객체
  • Qt MV는 Controller 없이 Model과 View를 Signal-Slot으로 직접 연결하며, 구조는 단순하지만 View의 역할이 커지고 결합도가 높을 수 있음
728x90

'CE' 카테고리의 다른 글

[CE] Memory(RAM)의 구조와 속도관련 표기법  (0) 2025.04.28
[CE] WebAssmbly (WASM)  (0) 2025.04.21
[C] LLP64 vs. LP64  (0) 2025.03.21
[Py] bytecode 분석 - dis 모듈  (0) 2025.03.11
Text File and Binary File: Hex Code  (0) 2025.03.11