요즘 개발자들 면접볼 때
"저는 A에서 A프로그램의 A를 맡아 개발했습니다." 라고 어필하는 것은 옛날이고
"저는 MVP를 2주 만에 개발할 수 있습니다." 라고 어필해야 먹힌다는 인스타 글을 읽고
여기에 덧붙여 쓰인 MVP... 가 무엇인지 몰라 찾아보았다.
일단
1. MVC
- Model → 데이터, 로직 (DB나 비즈니스 처리 담당)
- View → 화면 표시 (사용자에게 보여주는 UI 담당) Controller는 View에 “데이터만 전달”
- Controller → 중간 다리 (사용자의 요청을 받아서 Model과 View를 연결)
View에서 사용자 요청을 받고 → Controller에게 REST API 요청 → Service, Mapper 거쳐 데이터 반환 → View 데이터 출력
2. MVP
- Model → NoticeModel (DB 접근)
- View → NoticePage.vue (또는 JSP) Presenter가 시키는 대로 동작 (더 수동적)
- Presenter → NoticePresenter.js (또는 Java 클래스)
근데 여기까지 봐도, MVC랑 큰 차이를 모르겠다.
Presenter는 View를 ‘직접 제어’한다고 하는데 Controller한테 REST API요청 보내는 것도 직접 동작을 제어하는 게 아닌가. 뭐가 그렇게 크게 다른가? 하는 생각이 자꾸 들었다.
View는 Presenter를 알고 있다는데 ... 뭐 어쩌라는 건지 ?ㅠㅠ
- MVC → Controller는 “데이터 전달자”
- MVP → Presenter는 “화면 조종자”
이 설명을 보고. 아 스크립트가 MVP인가? 하는 생각이 들었다.
// View (템플릿)
<button @click="onAddNotice">등록</button>
// Presenter
function onAddNotice() {
noticePresenter.addNotice() // View가 Presenter에게 알림
}
// Presenter (로직 담당)
const noticePresenter = {
async addNotice() {
const res = await noticeModel.addNotice() // Model 호출 (API 요청)
view.showNoticeList(res.data) // View를 직접 조종
}
}
// Model (API 모듈)
const noticeModel = {
async addNotice() {
return axios.post('/api/notice', { title: '테스트' })
}
}
// View(객체)
const view = {
showNoticeList(list) {
document.querySelector('#list').innerHTML = render(list)
}
}
생소하다.
왜냐면
- MVP = 웹보단 안드로이드 앱 쪽에서 자주 쓰는 패턴 (UI 로직 세세히 제어할 때)
라고 한다.
그러니까 MVP는 서버와 통신하는 구조가 아니라 UI 자체의 구조라고 이해해야 한다.
해본 적이 없으니 당연히 모르지. (ㅋㅋ)
내가 해왔던 Vue ↔ Spring REST API 구조는 MVC다.
MVP는 “같은 프로그램 안에서 화면 로직을 더 깔끔하게 나누기 위한 UI 내부 패턴”
Vue ↔ Spring 같은 “서버-클라이언트 REST 구조”와는 다르다고 한다.
아래는 예시이고
보통 View 랑 Presenter는 .vue안에 두고
Model만 .js에 따로 빼면 좋다고 한다.
<button id="addBtn">등록</button>
<div id="message"></div>
<script>
// View는 Presenter에게 이벤트를 알림
document.querySelector('#addBtn').addEventListener('click', () => {
presenter.onAddClick(); // "등록 버튼 눌림!" 이라고 Presenter에게 알려줌
});
</script>
// Presenter (중간에서 로직 담당)
const presenter = {
async onAddClick() {
const result = await model.addNotice(); // Model에게 “글 등록해줘!” 요청
view.showMessage(result); // View에게 “결과 보여줘!” 명령
}
};
// Model (데이터 담당)
const model = {
async addNotice() {
const result = axios.post('/api/notice');
return result
}
};
// View (화면 조작)
const view = {
showMessage(msg) {
document.querySelector('#message').innerText = msg; // 화면에 결과 표시
}
};
3. MVVM
얘는 어렵지 않다. 지금 내가 프로젝트할 때 쓰고있는 vue에서 구현하는 모든 것들이 다 MVVM패턴이다.
- Model → NoticeService.js (백엔드 API 호출)
- ViewModel → Vue 컴포넌트의 script 영역 (Composition API에서 ref, reactive)
- View → Vue 템플릿 (<template>)
쉽게 설명하면
vue에서 ref, reactive 로 선언한 변수들이 전부 ViewModel이다.
ViewModel
: 화면(View)과 데이터(Model) 사이에서 데이터를 자동으로 이어주는 중간 매개체
4. Vue
전통적인 웹 구조 (HTML + JS + 서버의 JSP 등)
<!-- index.html -->
<html>
<body>
<div id="app"></div>
<script src="main.js"></script>
</body>
</html>
// main.js
document.querySelector("#app").innerHTML = "<h1>안녕</h1>";
이렇게 HTML 화면 + JS 명령 내리는 스크립트 가 있다.
JS가 HTML에 직접 접근해서 DOM 을 조작하는 것.
근데 Vue에서는 조금 다르다.
<template>
<h1>{{ msg }}</h1>
<button @click="changeMsg">변경</button>
</template>
<script setup>
import { ref } from 'vue'
const msg = ref('안녕 Vue!')
const changeMsg = () => {
msg.value = '바뀌었다!'
}
</script>
<templates>이 View
<script setup>이 ViewModel
Vue가 둘을 자동으로 “양방향 바인딩”
예를 들면 나는 지금 프로젝트 만들 때
vue프로젝트 안에
Item/Item.html Item/Item.js 만들고 js에서 src/component/Item/Item.vue 연결
Item.vue안에 <templates> 랑 <script setup> 있는 형식이다.
그래서 Vue를 단독 SPA로 쓰는 게 아닌
기존 웹 프로젝트 안에 Vue 컴포넌트를 부분적으로 끼워넣은 형태라고 한다.
서버 기반 MVC 프로젝트(Spring MVC)에 Vue를 부분적으로 붙인 형태
Item.js는 Vue를 실행하고 HTML에 붙이는 컨트롤러의 역할을 하고 있고
Item.vue는 View + ViewModel 본체
Item.html 은 Vue가 들어갈 공간
(서버)
↓
Item/Item.html ← 실제로 브라우저에 보이는 화면
↓
Item/Item.js ← 여기가 “Vue를 초기화”하는 JS
↓
Item/Item.vue ← Vue 컴포넌트 (template + script + style)
// Item.html
<div id="itemApp"></div>
<script src="./Item.js"></script>
// Item.vue
<template>
<div>
<h1>{{ title }}</h1>
<button @click="changeTitle">변경</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
const title = ref('안녕 Vue')
const changeTitle = () => title.value = '바뀜!'
</script>
| Item.html | View의 껍데기 | 서버나 HTML에서 Vue가 들어올 자리(#itemApp)를 잡아줌 |
| Item.js | Vue 구동기(엔트리) | .vue 컴포넌트를 HTML에 “마운트”시키는 중간다리 |
| Item.vue | 진짜 Vue 컴포넌트 (MVVM 구조) | 여기서 템플릿(View)과 데이터(ViewModel)가 한몸으로 묶임 |
'웹 개발 > 개념 정리' 카테고리의 다른 글
| [Sort] Bubble Sort, Selection Sort, Insertion Sort (C언어) (0) | 2026.03.09 |
|---|---|
| [WebOrder] JSON 객체로 보내고 받기 (0) | 2025.10.28 |
| 파라미터 / JSON 요청(3) 최종 예제 (0) | 2025.08.05 |
| 파라미터 / JSON 요청(2)에 따른 컨트롤러 ~ 와 제네릭 간단 설명 (4) | 2025.08.01 |
| @RequiredArgsConstructor (0) | 2025.06.17 |