Publishing Date:2020-09-29
배경지식
MVC 패턴
은 iOS 뿐만 아니라 소프트웨어를 만들 때 고려하는 디자인 패턴 중 하나이다. 디자인 패턴이란, 프로그래머가 소프트웨어를 만들 때 발생하는 공통적인 문제들을 해결하기 위해 만들어놓은 일종의 솔루션 템플릿이라고 할 수 있다. 싱글턴도 공통 인스턴스를 리턴하는 디자인 패턴이다.
MVC 패턴
MVC는 세 가지 컴포넌트의 약자이다.
M: Model V: View C: Controller
MVC 패턴을 적용한 애플리케이션에서 각 객체들은 위 세 가지 컴포넌트중 하나의 역할을 수행한다. 즉, 위 컴포넌트들은 애플리케이션에서 객체가 맡고 있는 역할
이라고 생각할 수 있다. 이 역할들은 동시에 애플리케이션에서 객체가 어떻게 통신하는지 를 정의할 수 있다.
역할
Model
은 UI와 관계 없이 애플리케이션에 관한 데이터를 담고 있다. UI와 관계가 없으나 자체의 데이터를 가지고 조작하고 처리하는 논리 연산을 모델에서 처리한다. 모델 객체는 데이터를 직접적으로 사용자에게 제공할 수 없다.
View
는 쉽게 말해서 사용자에게 보여지는 객체이다. 버튼, 이미지, 텍스트뷰를 포함해 사용자가 보고 상호작용할 수 있으며 뷰들의 집합이 곧 애플리케이션의 UI를 이룬다. 주의해야 할 점은, 뷰에서 모델이 가진 데이터를 보여줄 수는 있지만 모델 객체와의 직접적인 링크는 없다는 사실이다. 뷰는 모델과 직접 소통하거나 데이터를 가져올 수 없으며, 그저 Controller
에게 데이터를 받아 보여주고, 사용자가 편집할 수 있도록 사용자와 상호작용한다.
Controller
는 애플리케이션을 관리하는 객체이다. 사용자가 보는 뷰들과 모델간 일종의 동기화를 시켜준다. 즉, iOS에서 사용자가 텍스트 필드를 수정했을 때, 뷰에게서 사용자 액션을 받아 응답하고 수정된 데이터를 모델에 전달하는 등 뷰와 모델이 직접적으로 컨택할 수 없으므로 중간에서 중개자 역할을 해 준다.
iOS의 Cocoa Touch 프레임워크
는 코디네이팅 컨트롤러
와 뷰 컨트롤러
두 가지 기본 타입을 제공한다.
- 코디네이팅 컨트롤러: 애플리케이션 전체 혹은 일부 기능을 감독하고 관리한다. Delegation, notirication, Action 등의 기능이 수행된다.
- 뷰 컨트롤러: 화면에 표시하는 뷰를 관리하며, 해당 뷰에 대한 참조를 유지하고, 프레젠테이션 및 후속 뷰로의 전환 등 사용자에게 보여지는 화면을 책임진다. 모달 뷰나 기기의 방향 전환 등도 뷰 컨트롤러에서 담당한다. 이 때 뷰 컨트롤러는 여러 가지 프레임워크 객체에 대한 델리게이트 혹은 데이터 소스 객체인 경우가 많다!
iOS에서는 뷰 컨트롤러가 코디네이팅 컨트롤러의 역할을 겸하는 경우가 많다.
통신
그렇다면 각 객체는 어떻게 통신하는걸까? 역할에서 알 수 있었다시피, 모델과 뷰 사이에서는 직접적인 커뮤니케이션이 허용되지 않는다. 대신 모델과 뷰는 각각 컨트롤러와 통신함으로써 필요한 내용을 전달한다. 이를 그림으로 나타내면 대략 다음과 같다.
- User Action
먼저 뷰가 사용자의 입력을 받으면 미리 정해진 target-action 구조로 입력을 컨트롤러에 전달한다. 예를 들어 어떠한 뷰가 사용자의 입력을 받았을 때 뷰는 다른 객체의 메소드를 호출하는데 이 때 객체를타겟(target)
, 메소드를액션(action)
이라고 한다. iOS에서 타겟은 주로 뷰컨트롤러의 인스턴스를 의미한다. - Update Model
뷰의 변화를 전달받은 컨트롤러는 해당 액션을 바탕으로 모델을 업데이트한다. 이 때 컨트롤러는 모델에 자유롭게 접근할 수 있다. - Model Notification
모델은 자체 연산을 처리하고, 뷰에 업데이트 될만한 데이터를 컨트롤러에게 전달한다. 이 때 모델은 직접적으로 컨트롤러에 말을 걸 수는 없고,Notification
을 사용한다. 이 때 사용하는 Notification이 KVO이다. - Update View
컨트롤러는 모델에게서 받아온 데이터를 뷰에 업데이트해준다.
전통적인 MVC 패턴과의 차이점
위에서 설명한 MVC 패턴은 ViewController가 대부분의 일을 맡아서 하는 iOS의 구조 특성상 모델과 뷰 사이의 접점이 차단되어 있다. 그러나 전통적인 MVC 패턴에서는 컨트롤러가 뷰와 모델 사이에서 이벤트를 받아 전달해주는 것 외에도 모델에서 Observer
로 등록된 뷰 객체에게 Notify
할 수 있다.
출처: Apple Developer Docs
(iOS에서 사용하는 MVC 패턴을 먼저 알았기 때문에 설명 순서가 엉망이다.)
애플의 다른 디자인 패턴
MVC 외에 MVP
, MVVM
, VIPER
을 사용한다고 한다.
간단하게만 정리해보았다.
MVP
Model + View + Presenter
뷰 컨트롤러 대신 프레젠터를 사용한다. 프레젠터와 뷰는 일대일 관계 이다.
모델과 뷰 간의 의존성을 완전히 해결하였지만 뷰와 프레젠터간 관계가 밀접하다.
MVVM
Model + View + View Model
뷰 컨트롤러 대신 뷰 모델을 사용한다. 뷰와 뷰 모델은 다대일 관계 이다. 뷰는 자신이 사용할 뷰 모델을 선택해 데이터를 바인딩한다.
바인더를 통해 뷰와 뷰 모델 사이에 동기화되면서 뷰와 뷰 모델 사이의 관계 의존성을 감소시켰다.
VIPER
View + Interactor + Presenter + Entities + Router
- Entity: 모델 객체
- Interactor: 엔티티를 조작
- Presenter: Interactor에서 데이터를 가져와 View에 뿌려줌
엔티티를 제외한 다른 것들과 전부 상호작용함 - View: Presenter의 요청대로 디스플레이되고 사용자의 입력을 다시 Presenter에 전달
- Router: 화면 전환
Presenter가 언제 화면을 전환할지 알려주면 뷰 컨트롤러를 생성하여 Presenter과 연결함
왜 사용하는가
언급했다시피 디자인 패턴은 이미 선배 개발자들이 많은 경험을 통해 특정 상황에 맞는 구조를 미리 만들어놓은 것으로 재사용하기 좋은 구조이다. 이 중 특히 MVC 패턴은 소프트웨어를 설계할 때 객체간의 역할을 구분함으로써 각 객체가 본인의 역할만 수행하며 다른 객체와 분리되어있기 때문에 효율적일뿐 아니라 애플리케이션의 유연성
을 가지며 유지보수
에 유리하다.
그러나 iOS에서 MVC 패턴은 분리성에서 그다지 효율적이지 못하다. 전통적인 패턴에서 모델과 뷰를 분리하여 독립성을 확보하였지만, View
와 Controller
간 관계가 너무 밀접하여 제대로 된 분리성을 확보하지 못했다. View
와 Controller
사이의 관계가 밀접하다는 것은 곧 Controller
에서 View
의 생명주기와 같은 부분을 관장하고 있기 때문이다. 따라서 MVC 패턴이 아닌 MVVM 패턴을 사용하는 등 다른 디자인 패턴을 사용할 수 있다.
Reference
다음에서 발췌: Keur,Christian. ‘iOS Programming: The Big Nerd Ranch Guide (Big Nerd Ranch Guides).’ Apple Books.
네이버 iOS 부스트코스
애플 공식 문서
좋은 아키텍처에 관해서
아키텍쳐 패턴
Comments