iOS

iOS) Architecture Pattern

kangwook 2022. 9. 29. 22:06

오늘은 iOS 뿐만 아니라 범용적으로 사용되는 아키텍쳐 패턴에대해서 좀 다뤄보려고한다.

많이들 쓰이는 패턴이지만 나는 iOS개발자인만큼 iOS에 중점을 두고 정리를 하려고한다!

MVC Pattern(Model - View - Controller)

Model : 데이터에 관한 로직 담당(데이터 값 변경 및 관리)
View : 사용자에게 보여지는 화면 담당(UI)
Controller : Model과 View연결(Model 값을 View에 보여줌)

MVC 패턴에서 View와 Model은 절대로 서로에게 접근하면 안됨

ViewModelController만 접근할 수 있음

View에 사용자의 입력이 감지되거나 View의 변화가 생길 때 혹은 값의 변화가 있을 때?

  • Delegate와 DataSource를 사용하여 해결
  • delegate의 경우 사용자의 입력, 터치 등 이벤트가 발생했을 때 Controller가 그 이벤트를 처리하기 때문에 View가 직접적으로 Controller에 접근할 필요가 없음 
  • Model 역시 값의 변화를 Controller에 직접 전달하지 않고 Notification이나 KVO를 사용하여 Controller가 감지하여 처리할 수 있도록 해야 함

MVC패턴을 활용하여 개발하면 각각 역할이 나눠져 있기 때문에 생산성이 올라가지만 iOS의 경우 View와 ViewController간의 역할 분리가 완벽하지 않음

Controller가 맡는 부분이 많기 때문에 (ex. view life cycle 등) Controller가 커짐(massive view controller)


MVP(Model - View - Presenter)

Model : 데이터에 관한 로직 담당(데이터 값 변경 및 관리)
View : 사용자에게 보여지는 화면 담당(UI)
Presenter : Model과 View를 연결하고, 조정하는 역할

Presenter는 일반적으로 View에서 수행된 사용자의 동작에 반응하여 모델을 변경하고, 모델의 변경 사항을 뷰로 업데이트하는 역할을 함

MVC에서는 Controller가 View도 접근하고, Model에도 접근하는 특히, UIView의 lifecycle에 의해서 Controller가 강하게 연관되어 있었음

MVP에서는 Controller 대신 Presenter 개념을 도입하여, Passive View가 Life Cycle과는 아무 연관이 없고 어떤 레이아웃 코드도 Presenter에 안담겨 있게 만듦

MVC와의 차이점

  • MVC에서는 UIView나 UIViewController 둘 모두 View에 해당
  • MVP에서는 Presenter는 MVC와는 다르게 View(UIView, UIViewController)의 Life Cycle에 영향을 받지 않고 레이아웃 코드 역시 Presenter에 존재하지 않음
    • Presenter는 Model로부터 갱신된 데이터를 받아와 뷰를 갱신하는 역할을 함

MVVM Pattern(Model - View - View Model)

Model : 데이터 캡슐화, 로직 담당
View : 사용자에게 보여지는 시각적 요소, 컨트롤 표시(UI, Life Cycle 등)
View Model : Model 데이터를 View에 맞게 가공 및 처리(뷰에 반영될 데이터 비즈니스 로직 담당)

View는 오직 시각적인 요소로만 이루어져야 함 → View에서는 레이아웃, 애니메이션, UI요소들에 대한 초기화 작업 코드들만이 존재

ViewModel 사이에 ViewModel이 위치하게 됨

View Model은 View의 각 UI요소들에 대한 인터페이스를 제공 → View의 UI요소들과 ViewModel의 인터페이스를 연결시키는 바인딩 작업을 함

View의 비즈니스 로직은 ViewModel에 정의도어 있으며, 이에 맞춰 View가 갱신됨
→ ViewModel에서 데이터가 가공되어 View로 전달이 됨

ViewModel은 View로부터 사용자의 액션을 받아오고 → Model로부턴 데이터를 받아와 이렇게 받아온 데이터를 View에서 보여줄 값으로 가공
→ 그와 동시에 View는 ViewModel의 이러한 보여줄 값을 observing하고 있어 이에 맞춰 View를 갱신

  • MVVM 패턴에서 반응형 프로그래밍인 RxSwift를 사용하는 주된 이유

VIPER Pattern(View - Interactor - Presenter - Entities - Router)

View : 사용자에게 보여지는 시각적 요소(UI)
Interactor : data(Entities) 또는 networking과 관련된 비즈니스 로직
Presenter : UI관련 비즈니스로직, Interactor에서 메소드를 호출
Entities : 일반 데이터 객체 (Data Access Layer는 포함 안됨→이건 Interactor의 역할)
Router : VIPER 모듈간의 전환(segues)를 담당

VIPER는 application의 한 screen에만 적용될 수도, user story 전체에 적용될 수도 있음

데이터 상호작용 로직을 담당했던 MV(x)패턴의 Model의 기능은 VIPER에선 Interactor와 dumb한 data structure인 Entities로 나뉘어짐

Controller, Presenter, ViewModel의 오직 UI 표시 의무만 VIPER의 Presenter로 이동, 데이터 변환 기능은 이동하지 않음

Presenter는 View에서 event를 전달받아 Interactor를 통해 처리하고 View에 data와 함께 UI update 요청을 보내거나 Router를 통한 화면 이동을 처리

VIPER는 Router에 의해 풀리도록 되어있는 주소 네비게이션 책임을 명시적으로 다루는 패턴


RIBs Pattern(Router - Interactor - Builder - +ɑ)

RIBs 패턴은 Router, Interactor, Builder가 필수적으로 구성되고, 필요에 따라 Presenter와 View로 구성

Router : 자식 RIB를 attach, detach
Interactor : 비즈니스 로직을 수행해서 Router에 요청, Presenter로 data model 전달
Builder : RIBs의 모든 구성 요소를 생성하고 DI를 정의
Component : 부모 RIB Builder가 Component를 통해서 자식 RIB Builder로 의존성 주입
Presenter : data model을 view model 또는 반대로 변환하는 역할(Interactor ↔ View)
View : 사용자에게 보여지는 시각적 요소(UI)

Interactor는 비즈니스 로직을 포함하며 아래와 같은 작업들을 진행

  • Rx Sequence에 대한 Subscription 수행
  • child RIB를 attach할지 detach할지 결정
  • RIB의 state 변경에 대한 결정권을 가짐
  • 부모 자식 RIB간의 통신

Router는 Interactor에 대해 listening하며 RIBs를 attach 하거나 detach → 논리적 트리구조 형성

Builder는 RIB의 모든 컴포넌트 의 생성 및 DI 정의, Router를 output으로 반환

View는 UI화면을 구성하고 생성, 사용자로부터 들어온 event를 Presenter에게 전달하거나 UI를 업데이트

 

 

참조