세 가지 형태의 MVP
1) Taligent MVP
- Model, View, Presenter, Interactor, Selections, Commands 로 계층을 세분화
- Mike Potel(Taligent사 CTO) 이 MVC를 보다 세분화한 아키텍처로 MVP를 제시
2) Supervising Controller
- 간단한 프레젠테이션 로직은 뷰에서 처리, 복잡한 프레젠테이션 로직은 프리젠터가 처리
- 프레젠테이션 모델 페턴에서 끊겼던 모델과 뷰 사이의 옵저버 패턴이 부활
3) Passive View
- 로직을 배제하고 화면을 출력하는 소극적인(Passive)역할만을 담당하는 뷰
- 옵저버 바인딩을 사용하지 않으며, 모델과 뷰 사이의 관계도 끊어짐
- TDD의 유행과 맞물려 보다 테스터블한 코드 작성에 중점
Taligent MVP
- View - Controller 는 UI 계층 (Presentation)
- Model은 데이터를 관리하는 계층
MVC를 일반화, 세분화 하기
1) How do I display my data?
- 위의 그림에서 View에 해당한다. View는, 여러 개의 다른 View들로 구성될 수 있고 각 View들은 꼭 시각적으로 표시되지 않아도 된다.
2) How do events map into changes in my data?
- 위의 그림에서 Interactor에 해당한다.
3) How do I put it all together?
- 위의 그림에서 Presenter에 해당한다. Presenter는 MVC의 Controller와 유사하지만... 좀 더 높은, 추상화된 Application Level에 위치하고 Command와 Interactor랑 상호작용한다. 이 Presenter의 약자를 따서, Taligent가 제안한 Programming Model을 MVP(Model View Presenter)라고 이름을 지었다.
Presenter의 역할을 좀 더 직관적으로 요약하면, Event를 받아서 적절한 Command에 연결해주는 것이라고 볼 수 있다(본 MVP를 소개하는 원문에서는, 이것을 Business Logic을 제공한다고 표현했다).
MVP를 클라이언트 / 서버 구조까지 확장
- MVP 모델로 클라이언트 / 서버를 어떻게 구현할까?
▸ 보통 클라이언트와 서버는 Presneter에 따라 나뉠 수 있다. Model, Selection, Command는 서버에 속하고,
View, Interactor는 클라이언트에 속할 것이다. 그러면 Presnet는 클라이언트와 서버를 연결하는 역활이 될 것이다.
즉, 클라이언트와 서버 모두를 위한, 하나의 개념적인 Presenter가 존재한다.
▸ 클라이언트에서 입력 발생 -> 클라이언트 프레젠터가 서버측 프레젠터에 SQL등을 전달
Taligent MVP는 왜 주류가 되지 못하였는가?
- 지나친 계층의 분리 : 적절한 단위로 계층을 나누지 않으면 오히려 직관성을 저해
▸ 프레젠터는 결국 하나이므로, 클라이언트관련 코드가 서버관련의 코드들 보다 많아지거나, 그 반대의 상황도 생길 수 있다.
- iOS개발에서 사용되는 아키텍쳐들 중에도 RIBs나 VIPER 같은 다계층 아키텍처들이 존재
Supervising Controller (MVC를 60도 비틀기)
- 시간이 흐름에 따라 컨트롤러가 입력을 받는 GUI 개발환경이 줄고, 뷰가 입력을 처리하는 역할까지 담당하는 환경들이 많아짐
- Taligent에서 영향을 받았지만, 다계층을 채택하지는 않고, Applicaiton Model에서의 MVC패턴을 비틀어,Model - View -
Presenter의 역할을 재정립
- Model : 데이터를 관리하고 비즈니스 요구사항을 처리한다
- View : 애플리케이션의 화면이나 위젯을 구성하며, Model의 상태를 시각적으로 표현한다. 또한 사용자 이벤트를 해석하여 Presneter
로 요청을전달하며, 옵저버 패턴을 이용해, Model의 상태를 구독
- Presneter : 모델과 커뮤니케이션을 하며 표현 로직을 처리한다.
-언뜻보기에 SmallTalk MVC와 유사하지만, View가 사용자의 입력을 받는다는 점에서 차이점이 있다.
- *플로우 동기화(Flow Synchronization)와 *옵저버 동기화(Observer synchronization)을 모두 사용
▸ 뷰가 모델의 변경을 감지할 때는 옵저버 동기화 사용
▸ 프레젠터가 뷰를 조작할 때는 플로우 동기화 사용
*플로우 동기화(Flow Synchronization)
- 상위 계층의 데이터를 하위 계층에 전달해서 데이터를 동기화 하는 절차적 방법
- 장점: 서로 이웃해 있는 요소들끼리 데이터를 전달하므로, 데이터 흐름을 파악하기 쉽다
- 이웃한 화면들끼리 데이터를 공유해야하는 경우 플로우 동기화가 효율적
▸ UITableVIew에서 cell을 탭했을 때 특정화면으로 이동하면서 해당 화면에 선택된 cell의 데이터를 동기화
▸ UIViewController를 Push하면서 이동하는 화면으로 데이터를 넘겨줄 때
- 단점: 동기화할 모든 요소들의 참조를 갖고있어야 하므로 참조관리가 복잡해질 수 있다
*옵저버 동기화(Observer synchronization)
- 옵저버 페턴으로 상위 계층을 하위 계층이 감시하고 이벤트 통지를 받아 데이터를 동기화하는 선언적 동기화 방식
- 장점: 여러 곳에서 공통으로 추적해야 할 데이터가 있는 경우 데이터를 동기화하기 쉽다.
- 멀리 떨어져 있는 곳들에서 데이터를 공유하는 경우
▸ UIViewController 나 UIView의 계층이 깊게 중첩되어 있는 경우
▸ 여러 탭에서 데이터를 공유해야 하는 경우
- 단점: 데이터가 변경될 때 마다 동기화 처리가 이루어져서 언제 데이터가 동기화 되는지 파악하기 어렵다.
Passive View 옵저버 동기화를 포기한 뷰
- Passive view는 이름처럼 View를 매우 가볍게 만드는 것이다. Passive View의 View는 모델을 의존하지 않으며 오로지 Presneter만 의존한다. Presenter는 View와 Model 사이에서 중재자 역활을 하며 대부분의 표현 로직을 처리한다.
- View는 모든 상태와 로직을 프레젠터에 추출당해 오직 UI 갱신과 관련된 수동적인 역할만 담당
- 테스터블한 코드를 위해 View의 사용성은 최대한 적게 해야한다.
- TDD와 밀접하게 연관되어있다. Passive View의 표현 로직에 대한 테스트 가능성이 Supervising Controller 보다 더 높다. 하지만
Presenter가 View를 더 많이 의존해야 하고, 동기화 로직을 더 많이 작성해야만 한다
- View의 테스트 가능성에 대한 고민은 MVVM으로 넘어가면서 중요한 주제로 떠오른다.
Passive View Vs Supervising Controller
- Supervising Controller는 표현 로직을 Presenter와 View에 분배한다. View는 모델의 상태를 화면에 표현하고, 상태를 표현하는 데
에 필요한 간단한 로직만을 책임진다. Presenter는 사용자의 입력을 해석하고 복잡한 표현 로직을 처리하며, View와 Model의 사이에서
둘을 동기화한다.
- Passive View의 상태 변경 흐름은 Supervising Controller에 비해 단순하다.
MVP로 개발시 Supervising 과 Passive View 중 어느 것이 적합할까?
- 테스트 코드 작성 유무
▸ 프레젠테이션 로직이 UI와 완전히 격리되어 Passive View가 적합
- 모델과 관련된 처리를 보다 간단하게 처리하고 싶은가?
▸ 모델로부터 직접 변경을 받는 Supervising Controller가 적합
- 간단한 프레젠테이션 로직 과 복잡한 프레젠테이션 로직을 구분하기 어려운가?
▸ Passive View가 적합
UIKit 환경에서 MVP(Passive View)
'Architecture' 카테고리의 다른 글
iOS(UIKit)에서의 Coordinator Pattern (0) | 2023.09.18 |
---|---|
iOS(UIKit)에서의 CleanArchitecture+MVVM 예시 뜯어보기 (0) | 2023.09.15 |
MVVM in iOS (0) | 2023.09.04 |
MVC(Model - View - Controller) (0) | 2023.08.16 |
아키텍처(Architecture) (0) | 2023.08.13 |