디자인패턴 질문
27
投稿した質問数 7
안녕하세요 큰돌님! 저는 백엔드 개발을 주력으로 하다 보니, MVP나 MVVM 같은 프론트/UI 쪽 아키텍처 패턴은 텍스트 개념서로만 접하다 보니 와닿지가 않더라고요. 단순 암기를 하자니 이해를 기반으로 해야 면접에서도 자연스럽게 나올 텐데, 겉핥기 식으로 외워서 달달 말하는 건 오히려 역효과가 날 것 같아 아쉬움이 있었습니다. 혹시 실무에서 쓰이는 형태나 아주 직관적인 예시(코드 등)를 통해, 각 패턴이 왜 등장하게 되었고 어떤 장단점 및 차이가 있는지 쉽게 이해할 수 있는 팁을 조금 얻을 수 있을까요?
제가 지금까지 이해하고 정리한 수준은 대략 이렇습니다: (하지만, 정리를 하면서도 대충이라도 코드가 떠오르거나 하지 않다보니 뭔가 제 것이 아닌것 같은 느낌이 들어서 고민이 됩니다.)
MVC: 요청 받는 것, 데이터 처리 및 CRUD, 화면에 표시하는 것을 구분하기 위한 목적으로 역할을 분류해서 코드 가독성 및 유지보수 높임. 그런데 컨트롤러 안에서 m과 v의 변경사항을 모두 다루고 전달까지 하니 점점 커지고, M과 V가 서로 직접 참조할 수 있는 구조 때문에 역할이 꼬이고, 그러면 단위 테스트도 어려워짐.
MVP: 그래서 M과 V가 서로 직접 참조할 수 없게 만듦, 하지만 MVP에서도 여전히 MVC의 컨트롤러가 비대해지는 문제는 해결하기 어려움.
MVVM: 그래서 등장한 것이 MVVM. 데이터 바인딩을 통해서 뷰가 자동으로 업데이트되게 만들어 코드가 좀 줄어듦. 결과적으로 MVC의 단점이었던 '컨트롤러 비대화'와 'M과 V의 직접 참조 위험성' 두 가지 모두를 잡은 패턴. 단점으로는.. 그냥 그만큼 구조가 더 복잡해졌다?
回答 2
0
안녕하세요 지훈님 ㅎㅎ
MVC
"요청 받는 것, 데이터 처리 및 CRUD, 화면에 표시하는 것을 구분"
-> 이건 Spring MVC(Model 2) 설명입니다. 사실 MVC는 세 갈래인데요 — Smalltalk MVC(V가 M을 구독) / Model 2(Spring·Rails, 구독 없음) / Cocoa MVC(Controller가 M·V 중재). 이 셋이 이름만 같고 다른 물건입니다.
Spring MVC엔 "Model이 변하면 View가 갱신된다"가 아예 없습니다. 상태 변화에 반응할 화면 자체가 없으니까요.
"M과 V가 서로 직접 참조할 수 있는 구조"
-> 맞습니다 단, Smalltalk MVC 한정입니다. Cocoa MVC는 V가 M을 직접 참조 안 합니다.
class TodoView {
constructor(model) {
this.model = model; // ← View가 Model을 안다
model.subscribe(() => this.render());
}
render() {
const left = this.model.items.filter(i => !i.done).length; // 도메인 규칙이 뷰로 샘
}
}
"단위 테스트도 어려워짐"
정확합니다. 저 filter 한 줄 때문에 뷰를 띄워야만 테스트 가능해집니다.
"컨트롤러 안에서 다 다루니 점점 커짐"
문제 자체는 실재합니다. 다만 이건 Cocoa MVC에서 터지는 현상이고, iOS에서는 Massive View Controller라고 부릅니다.
MVP
"M과 V가 서로 직접 참조할 수 없게 만듦"
-> 맞습니다. View를 인터페이스로 추상화해서 진행한다고 보면 됩니다.
interface TodoView {
fun showTodos(items: List<Todo>)
fun showLoading(); fun hideLoading(); fun showError(msg: String)
}
class TodoPresenter(private val view: TodoView, private val repo: TodoRepo) {
fun onSubmit(text: String) {
view.showLoading()
repo.add(text)
view.showTodos(repo.all()) // 갱신
view.hideLoading()
}
}
백엔드 예시로는 헥사고날의 Port/Adapter 그 자체라고 보시면 됩니다. Activity가 Adapter, 테스트할 땐 FakeView 주입 = Mock Repository 주입.
"MVP에서도 비대해지는 문제는 해결 어려움"
정확히는 MVP의 비대화는 "다 떠안아서"가 아니라 갱신을 일일이 명령해야 해서입니다. "화면 상태" 하나 늘 때마다 view.xxx() 메서드가 늘어납니다.
MVVM
"그래서 등장한 것이 MVVM"
-> 아닙니다. MVVM은 MVP를 고치려고 나온 게 아닙니다. 2005년 MS의 John Gossman이 만들었고, 이유는 WPF에 이미 강력한 선언형 바인딩 엔진이 있었기 때문입니다. 기술이 먼저 있었고 패턴이 따라온 것이지, 순차 진화가 아닙니다.
"데이터 바인딩으로 뷰가 자동 업데이트, 코드가 줄어듦"
-> 정확합니다.
class TodoViewModel(private val repo: TodoRepository) : ViewModel() {
private val _uiState = MutableStateFlow(TodoUiState())
val uiState = _uiState.asStateFlow() // ← View 타입이 등장조차 안 함
fun add(text: String) = viewModelScope.launch {
_uiState.update { it.copy(isLoading = true) }
runCatching { repo.add(text) }
.onSuccess { _uiState.update { s -> s.copy(items = repo.all(), isLoading = false) } }
.onFailure { e -> _uiState.update { s -> s.copy(error = e.message, isLoading = false) } }
}
}
@Composable
fun TodoScreen(vm: TodoViewModel) {
val state by vm.uiState.collectAsStateWithLifecycle()
if (state.isLoading) CircularProgressIndicator()
Text("남은 일: ${state.items.count { !it.done }}")
}
MVP는 Presenter가 View를 알았지만, MVVM은 ViewModel이 View를 아예 모릅니다. 상태만 노출하고 뷰가 알아서 구독합니다.
"'컨트롤러 비대화'와 '직접 참조' 두 가지를 모두 잡음"
-> 절반만 맞습니다.
직접 참조 → 맞습니다.
비대화 → 안 잡힙니다. MVVM 써도 ViewModel은 똑같이 뚱뚱해집니다.
비대화의 근본 해법은 패턴 교체가 아니라 계층 분리(Service·UseCase)입니다.
"단점으로는.. 그냥 구조가 복잡해졌다?"
-> 구체적으로 얘기하는 게 중요한데요. 바인딩이 암묵적 의존이라 추적이 안 됩니다. 값이 왜 안 바뀌는지 콜스택을 못 따라가고, 불필요한 리컴포지션/리렌더 성능 이슈가 생기는 단점이 있습니다. 반면 MVP는 view.showLoading()이 코드에 박혀 있어 눈으로 따라갈 수 있다고 보면 됩니다.
또 질문 있으시면 언제든지 질문 부탁드립니다.
좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)
감사합니다.
강사 큰돌 올림.
0
안녕하세요, 인프런 AI 인턴입니다. 이지훈님!
백엔드 개발자 관점에서 MVP·MVVM 같은 프론트엔드 아키텍처 패턴이 추상적으로 느껴진다면, 각 패턴을 단순히 암기하기보다 어떤 문제를 해결하기 위해 등장했는지, 그리고 데이터 흐름과 책임이 어떻게 나뉘는지를 중심으로 이해하는 것이 좋습니다.
특히 MVC와 Flux를 비교한 아래 답변에서는 다음 내용을 직관적으로 설명하고 있습니다.
- MVC와 Flux가 해결하려는 문제
- Flux의 단방향 데이터 흐름
- 상태를 중앙에서 관리할 때의 장단점
- 단순한 기능에서도 Flux 구조가 복잡해질 수 있는 이유
- 프로젝트 규모와 요구사항에 따라 적합한 패턴이 달라지는 이유
flux 패턴 질문
MVP와 MVVM도 마찬가지로 각각 View와 비즈니스 로직, 상태 관리의 책임을 분리해 UI 코드가 복잡해지는 문제를 해결하려는 패턴입니다. 따라서 면접에서는 패턴의 정의만 말하기보다, “기존 구조에서 어떤 문제가 발생했고, 이 패턴이 그 문제를 어떻게 개선했으며, 어떤 복잡성을 새롭게 가져오는가”를 설명하면 이해를 기반으로 답변하기 좋습니다.
추가로 디자인 패턴의 면접 우선순위와 학습 순서에 대한 답변도 참고하실 수 있습니다.
디자인패턴 질문
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
팩토리 패턴
0
45
2
싱글톤 패턴 구현방법
0
50
2
라이브러리 프레임워크 차이 질문
0
51
1
프로젝트 질문 드립니다!
0
41
2
추상화 질문
0
33
2
직렬화 역직렬화 질문 드립니다!
0
50
2
안녕하세요 큰돌님!
0
71
2
REST API (Self-descriptive messages)
0
64
1
시스템 엔지니어 관련 질문입니다.
0
119
2
오버라이딩 관련하여 질문드립니다.
0
103
2
교착상태의 4가지 필요조건이 필요충분조건이 아닌 이유
0
132
1
렌더 트리, 렌더 레이어와 그래픽 레이어
0
83
2
로컬스토리지, 세션스토리지, 쿠키의 공통점
0
87
1
IPv4가 IPv6보다 빠른 경우
0
173
2
UDP가 전송계층의 역할을 못하는 건 아닌지
0
82
1
Path MTU 발견하였음에도 패킷 분할이 필요한 이유?
0
95
2
교재의 LFU 알고리즘에서 6번이 왜 히트인가요?
0
104
2
페이지 교체 알고리즘? 프레임 교체 알고리즘?
0
113
2
Static 키워드가 메모리에 올라가는 시점
0
103
2
헤더 압축부분 질문드립니다
0
105
2
공유 캐시 관련 질문 드립니다.
0
79
2
컨텍스트는 context와 contextual information으로 나눠진다는게 무슨뜻인가요?
0
260
1
회선과 대역폭의 관계
0
102
2
44강 질문
0
142
2

