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의 동작 흐름
- 사용자가 View를 통해 입력함 (event 발생).
- View는 입력을 약속된 방식으로 Controller로 전달함.
- Controller는 입력을 해석하고 이에 따라 Model을 갱신하거나 View를 조작.
- 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의 구조와 동작
- View의 버튼 등 UI 요소에 Command가 바인딩됨
- 사용자가 버튼을 클릭하면 해당 Command 객체의
execute()메서드가 호출됨 - ViewModel 내 로직이 실행되어 Model을 갱신하거나 데이터를 처리함
- 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에는 없는 요소)
동작 흐름
- Model이 데이터를 관리하고 제공.
- View가 UI로 데이터를 표시.
- 사용자의 입력은 View 또는 Delegate가 처리하고, Model을 직접 갱신.
- 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의 역할이 커지고 결합도가 높을 수 있음
'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 |