아키텍처 패턴에 대하여 (MVC, MVP, MVVM)
CS

아키텍처 패턴에 대하여 (MVC, MVP, MVVM)

1. 개요

아키텍처는 시스템을 구성하는 요소와 요소들 사이의 관계, 각 요소의 책임과 역할을 설정해서

소프트웨어를 구조화한 것을 의미하며, 소프트웨어의 뼈대(청사진) 역할을 한다.

 

아키텍처 패턴이란 소프트웨어의 아키텍처에서 발생하는 공통적인 문제들을 해결하기 위한

일반적이고 검증된 아키텍처를 형식화(패턴화)한 것을 의미한다.

디자인 패턴 vs 아키텍처 패턴
디자인 패턴은 소프트웨어 설계(디자인)에서 발생하는 공통적인 문제를 해결하기 위해
설계 방식을 형식화(패턴화) 한 것을 의미한다.

두 개념 모두 공통적이고 일반적인 문제에 대한 솔루션을 제공한다는 점에서 유사하다.

그러나 아키텍처 패턴은 추상적인(고수준, High-Level) 의미에서 구조와 뼈대를 다루지만
디자인 패턴은 코드 수준(비교적 저수준)의 설계를 의미한다.

따라서 아키텍처 패턴의 범주가 디자인 패턴보다 클 뿐 디자인 패턴을 포함하는 개념으로 보긴 어렵다.
대표적인 디자인 패턴(Singleton, Delegate 등)과 비교해보면 그 차이를 쉽게 알 수 있다.

대표적으로 사용하는 아키텍처 패턴은 MVC, MVP, MVVM 등이 있다.


2. 대표적인 아키텍처 패턴 (MV*)

소프트웨어를 Model과 View로 구성한 대표적인 아키텍처 패턴에는 

MVC(Model-View-Controller), MVP(Model-View-Presenter), MVVM(Model-View-ViewModel)이 있다.

 

Model은 데이터 저장, 처리 등 데이터와 관련된 작업을 담당하는 요소이며,

View는 사용자에게 보여지고 데이터를 화면에 표시하는 역할을 한다.

모든 데이터는 Model에서 View 방향으로 흐른다.

 

위 3가지 아키텍처 패턴에는 Model과 View에서 오는 신호를 해석하고 전달해주는 중개자가 존재한다.

그 중개자는 각각 Controller, Presenter, ViewModel이 담당한다.

1) MVC

전통적인 MVC 패턴

전통적인 MVC 패턴에서 Controller는 사용자의 입력(사용자 이벤트)을 받아서 Model을 업데이트하고

여러 View 중에서 업데이트된 데이터를 표시할 View를 선택한다.

선택된 View는 Model의 데이터를 이용하여 자신을 직접 업데이트한다.

Controller와 View는 1:N 관계이다.

 

Controller는 View와 Model에 의존하고 View 역시 Model에 의존한다.

이렇듯 각 구성 요소들이 서로 복잡한 의존 관계를 가지면 소프트웨어의 유지 보수가 어렵다.

 

따라서 View와 Model을 독립시키고자 iOS에서는 Cocoa MVC라는 새로운 패턴을 제시한다.

Cocoa MVC

전통적인 MVC 패턴과 달리 Controller는 사용자 입력을 받지 않으며 View의 업데이트를 담당한다.

View는 target-action 디자인 패턴으로 Controller에게 사용자 이벤트를 전달하고,

Controller가 전달한 데이터를 이용하여 자신을 업데이트하는 역할을 한다.

Model은 Controller의 요청으로 데이터가 변경되면 Notificaton 또는 KVO 패턴으로 변경을 알린다.

 

Controller가 View와 Model에 의존하는 관계(그림의 실선 화살표)는 전통적인 MVC 패턴과 동일하지만

Cocoa MVC에서 View와 Model은 서로 독립적이다.

 

View는 자신을 관리하는 Controller의 존재를 알 필요가 없다.

Model 역시 데이터 변경을 알릴 뿐 알림을 받는 주체가 누구인지 알 필요가 없다.

Controller는 View로부터 사용자 이벤트를 받거나 Model로부터 변경된 데이터를 받아서

신호를 해석하고 각 요소에 전달해준다.

 

MVC 패턴은 iOS의 UIKit이 제공하는 기본 구조이기 때문에 구현하기 쉽다는 장점이 있지만

View와 Controller가 밀접한 관계를 가지므로 떼어놓기 어렵다는 단점이 있다.

UIKit 프레임워크의 UIViewController와 UIView의 관계를 생각하면 편하다.

이런 문제를 개선하고자 MVC 패턴으로부터 MVP 패턴이 파생됐다.

2) MVP

MVP 패턴

MVP 패턴의 Presenter는 MVC의 Controller와 동일한 역할을 한다.

마찬가지로 View로부터 사용자 이벤트를 받고 Model의 데이터를 업데이트하거나

Model로부터 요청한 데이터를 받아서 View를 업데이트한다.

MVP의 View는 UIView와 UIViewController를 모두 포함하는 개념이다.

단, Presenter는 Controller와 다르게 하나의 View만 담당하고 View의 추상체(프로토콜)에 의존한다.

View 역할을 하는 UIViewController 객체는 Presenter 객체를 소유하고 있지만

Presenter 객체는 프로토콜로 추상화된 UIViewController의 Delegate를 소유한다.

 

따라서 View에 대한 Presenter의 의존성을 줄임으로써 독립성을 확보하고

테스트가 가능해진다는 장점이 있다.

View와 Model은 Cocoa MVC와 마찬가지로 완전 독립

하지만 Presenter와 View의 연관성을 완전히 제거하지 못하여

하나의 Presenter가 하나의 View에만 사용되는 등 유연성이 떨어지는 문제가 있었다.

 

그래서 이를 개선시킨 MVVM이 등장했다.

3) MVVM

MVVM 패턴

MVVM의 ViewModel은 MVP의 Presenter와 유사한 역할을 하는데

View에 표시할 데이터를 가공하고 처리해서 ViewModel이라고 부른다.

 

ViewModel은 View와 양방향 바인딩으로 상호작용한다.

그렇게 하면 View에 입력되는 사용자 이벤트가 ViewModel에 전달될 뿐만 아니라,

ViewModel이 Model에 요청한 데이터를 가공 및 처리한 결과가 View에 반영된다.

View는 바인딩된 데이터를 사용해 자신을 직접 업데이트한다.

 

양방향 바인딩을 구현하는 방법은 RxSwift, Combine 등의 FRP 라이브러리를 사용하거나

프로퍼티 옵저버, Delegate 패턴, KVO 패턴을 이용하는 방법이 있다.

FRP: Functional Reactive Programming

MVVM 패턴은 ViewModel이 View의 존재를 알 필요가 없기 때문에

View와 Model 뿐만 아니라 ViewModel과 View의 완전 독립이 가능하다.

즉, 하나의 ViewModel이 여러 View에 사용될 수 있다. (ViewModel과 View은 1:N 관계)

이처럼 MVVM 패턴은 각 요소의 테스트와 소프트웨어의 유지, 보수가 용이하다는 장점이 있지만

ViewModel을 설계하기 어렵다는 단점이 있다.


참고 문서

iOS 아키텍처 패턴

MVC, MVP, MVVM (feat. Clean Architecture)

아키텍처 패턴 - 위키백과