핵심 인사이트 (3줄 요약)
- 본질: MVC (Model-View-Controller, 모델-뷰-컨트롤러)는 사용자 인터페이스 코드를 데이터(Model), 화면 표현(View), 입력 처리 제어(Controller)로 분리하여 각 관심사가 독립적으로 변경될 수 있게 하는 가장 널리 사용되는 UI 아키텍처 패턴이다.
- 가치: Model이 변경되어도 View 코드를 수정할 필요가 없고, UI 디자인이 바뀌어도 비즈니스 로직이 영향받지 않으므로 프론트엔드·백엔드 개발의 병렬 진행과 단위 테스트가 용이해진다.
- 판단 포인트: MVC의 가장 흔한 함정은 Controller가 비대해지는 "뚱뚱한 컨트롤러(Fat Controller)" 문제다. Controller는 입력을 받아 Model에 위임하고 View를 선택하는 교통정리 역할만 해야 하며, 비즈니스 로직이 Controller에 직접 구현되면 설계가 무너진다.
Ⅰ. 개요 및 필요성
MVC 패턴은 1970년대 Smalltalk-80 언어의 GUI 프레임워크에서 처음 도입되었으며, 트리그베 린스카우그(Trygve Reenskaug)가 설계했다. 이후 웹 시대에 서버 사이드 렌더링(Rails, Django, Spring MVC)과 클라이언트 사이드 렌더링(Angular, React의 개념적 기반)으로 재해석되어 현대 웹 개발의 기반 패턴이 되었다.
MVC가 없던 시절 웹 코드는 HTML, SQL, 비즈니스 로직이 한 파일에 뒤섞인 "스파게티 코드"였다. UI 변경 시 데이터베이스 쿼리도 수정해야 하고, 비즈니스 규칙 변경 시 HTML도 수정해야 하는 상황이었다. MVC는 이 혼합을 세 역할로 분리하여 독립적 진화를 가능하게 했다.
┌─────────────────────────────────────────────────────────────┐
│ MVC 구성 요소와 상호작용 흐름 │
├─────────────────────────────────────────────────────────────┤
│ 사용자(User) │
│ │ 1. HTTP 요청 │
│ ▼ │
│ Controller ─────────────▶ Model │
│ (입력 처리·흐름 제어) 2. 비즈니스 로직 처리 │
│ │ │ │
│ │ 3. 결과 데이터 전달 │ │
│ ▼ │ │
│ View ◀──────────────────────┘ │
│ (화면 표현) │
│ │ 4. HTML/JSON 응답 │
│ ▼ │
│ 사용자(User) │
└─────────────────────────────────────────────────────────────┘
Model은 옵저버 패턴(Observer Pattern)을 통해 상태 변화를 View에 알릴 수 있다. 이 연결이 MVC의 핵심이자 Push 방식과 Pull 방식의 변형이 생기는 원천이다.
- 📢 섹션 요약 비유: 식당에서 손님(사용자)이 웨이터(Controller)에게 주문하면, 웨이터는 주방(Model)에 전달하고, 완성된 요리를 접시(View)에 담아 손님에게 내온다. 웨이터가 직접 요리하면 MVC가 무너진다.
Ⅱ. 아키텍처 및 핵심 원리
MVC의 세 요소는 명확한 역할 경계를 가진다. Model은 데이터·비즈니스 로직·상태를 소유하며 View나 Controller를 전혀 알지 못한다. View는 Model의 데이터를 화면으로 표현하되 비즈니스 로직이 없다. Controller는 사용자 입력을 받아 Model을 업데이트하고 적절한 View를 선택하는 교통 정리자다.
| 항목 | 설명 | 포인트 |
|---|---|---|
| Model | 데이터·비즈니스 로직 / 자신의 상태와 규칙 | View, Controller |
| View | 화면 표현·렌더링 / Model 데이터 | 비즈니스 로직, DB |
| Controller | 입력 처리·흐름 제어 / Model, View | 비즈니스 로직 세부 사항 |
┌─────────────────────────────────────────────────────────────┐
│ 서버 사이드 vs 클라이언트 사이드 MVC 비교 │
├─────────────────────────────────────────────────────────────┤
│ 서버 사이드 MVC (Spring MVC): │
│ HTTP 요청 → DispatcherServlet(C) → Service(M) → View Template│
│ │
│ 클라이언트 사이드 MVC (Angular 계열): │
│ DOM 이벤트 → Controller → Model 상태 변경 → View 리렌더링 │
│ │
│ 차이: 서버 사이드는 요청마다 View 재생성 │
│ 클라이언트 사이드는 상태 변화에 반응적 View 갱신 │
└─────────────────────────────────────────────────────────────┘
Spring MVC의 DispatcherServlet은 Front Controller 패턴을 구현한다. 모든 HTTP 요청이 중앙 DispatcherServlet을 거쳐 적절한 Controller로 라우팅되며, 이 구조가 인터셉터(Interceptor), 필터(Filter), 예외 처리의 중앙 집중 관리를 가능하게 한다.
- 📢 섹션 요약 비유: 교통 신호등(Controller)은 차량(요청)이 어느 차선(View)으로 갈지 지시하고, 도로 규칙(Model)은 속도 제한·우선순위를 정한다. 신호등이 직접 차를 만들거나 도로를 포장하지 않는다.
Ⅲ. 비교 및 연결
MVC는 다양한 파생 패턴(MVP, MVVM, MVI)의 기원이다. 각 파생 패턴은 MVC의 특정 약점을 보완하기 위해 등장했다.
| 비교 축 | A | B |
|---|---|---|
| View 역할 | 직접 Model 참조 가능 | Presenter를 통해서만 / 데이터 바인딩으로 ViewModel 연결 |
| 테스트 용이성 | Controller 테스트 용이 | Presenter 단위 테스트 용이 / ViewModel 단위 테스트 최적 |
| 사용 환경 | 웹 서버 사이드 | Android, iOS / WPF, Angular, Vue, React |
| View-Model 결합 | 중간 | 낮음 / 가장 낮음 (데이터 바인딩) |
MVC는 계층형 아키텍처의 프레젠테이션 계층에서 사용되는 패턴이다. 계층형 아키텍처가 시스템 전체 구조를 정의한다면, MVC는 프레젠테이션 계층 내부 구조를 정의한다.
- 📢 섹션 요약 비유: MVC는 출판사(전체 계층형 시스템) 안에서 편집팀(컨텐츠 조직)이 내용 담당·디자인 담당·마케팅 담당으로 나뉜 것과 같다. 출판사 구조(계층형)가 있고 그 안에서 편집팀 역할 분담(MVC)이 이루어진다.
Ⅳ. 실무 적용 및 기술사 판단
Spring MVC 기반 프로젝트에서 MVC 위반의 가장 흔한 형태는 Controller에 비즈니스 로직이 직접 구현되거나, View(JSP, Thymeleaf 템플릿)에 SQL 쿼리나 복잡한 계산 로직이 들어가는 것이다. 감리 관점에서는 이런 구조가 유지보수 비용 증가의 직접 원인이 된다.
판단 체크리스트
- Controller 메서드의 코드 줄 수가 20줄 이하로 관리되는가?
- Controller가 비즈니스 로직을 Service 계층에 완전히 위임하는가?
- View(템플릿)에 비즈니스 계산 로직이 없는가?
- Model(도메인·서비스)이 View나 Controller를 참조하지 않는가?
- Controller 단위 테스트가 Mock Service를 통해 독립적으로 수행되는가?
- 📢 섹션 요약 비유: 판사(Controller)는 법조문(Model)을 해석하여 판결(View 선택)을 내린다. 판사가 직접 법을 만들거나 판결문을 직접 출력하면 삼권분립(MVC)이 무너진다.
Ⅴ. 기대효과 및 결론
MVC를 올바르게 적용하면 프론트엔드 개발자와 백엔드 개발자가 Controller를 인터페이스로 병렬 개발할 수 있다. View는 독립적으로 테마(Theme)나 레이아웃을 변경할 수 있고, Model의 비즈니스 규칙은 View 변경과 무관하게 단위 테스트할 수 있다.
한계는 MVC가 데이터 바인딩과 실시간 반응형 UI에 적합하지 않다는 점이다. 현대 SPA(Single Page Application)에서는 MVVM 또는 단방향 데이터 흐름(Flux, Redux) 패턴이 더 적합하다. 또한 대규모 시스템에서 View와 Model 간의 복잡한 다대다 관계가 생기면 MVC의 명확성이 흐려진다.
미래 방향으로는 ① 리액티브 프로그래밍과 MVVM의 결합(Angular Signals, Vue 3 Composition API), ② 서버 컴포넌트(React Server Components)로 서버-클라이언트 MVC 경계의 재정립, ③ AI 기반 View 자동 생성이 주목받고 있다.
MVC는 "UI 코드의 혼돈을 세 역할로 정리하는 가장 기본적인 설계 어휘"로, 모든 UI 아키텍처 패턴의 출발점으로 기억해야 한다.
- 📢 섹션 요약 비유: 연극에서 배우(View)는 대본(Model)에 따라 연기하고, 연출가(Controller)는 무대 흐름을 지시한다. 배우가 연출까지 하면 공연이 혼란스러워지고, 연출가가 무대 위에서 연기하면 객석이 웃는다.
📌 관련 개념 맵
[UI 스파게티 코드] → [MVC 패턴] → [프레젠테이션 계층 내부 구조] → [MVP·MVVM 파생] → [SPA·리액티브 UI]
| 개념 | 연결 포인트 |
|---|---|
| Front Controller 패턴 | Spring MVC의 DispatcherServlet 구현 기반 |
| Observer 패턴 | Model이 View에 상태 변화를 알리는 메커니즘 |
| MVVM | MVC의 View-Controller 결합을 데이터 바인딩으로 분리한 파생 |
| 계층형 아키텍처 | MVC가 위치하는 프레젠테이션 계층의 상위 구조 |
📈 관련 키워드 및 발전 흐름도
[GUI 스파게티 코드] → [MVC 패턴(Reenskaug, Smalltalk)] → [웹 서버 사이드 MVC(Rails·Spring)] → [클라이언트 사이드 MVC(Angular)] → [MVVM·Flux] → [리액티브 컴포넌트·서버 컴포넌트]
👶 어린이를 위한 3줄 비유 설명
- 게임에서 캐릭터 정보(Model)가 바뀌면 화면(View)이 바뀌고, 조이스틱 입력(Controller)이 캐릭터를 움직여요.
- 조이스틱(Controller)은 직접 캐릭터를 그리지 않고, 화면(View)은 직접 캐릭터를 움직이지 않아요.
- 각자의 역할을 지키면 그래픽을 바꿔도 조이스틱 코드를 건드릴 필요가 없어요!