 Apple Lover Developer & Artist

영속적인 디자인에 현대의 공감을 채워넣는 공방입니다

 Apple/iOS Dev Challenges

[Challenge] 🛠️ iOS 앱 설계 퓨전 레시피 3부 - 책임의 밀당

singularis7 2023. 2. 20. 18:45
반응형

Overview

UIKit 애플리케이션의 기본 개발 패턴은 Cocoa MVC였다. 대표적으로 View Controller와 같이 책임이 결합된 경우를 생각해 볼 수 있다. 이때, 개발자가 코드를 잘 못 디자인하면 한 객체의 책임이 커져버리는 문제가 생긴다. 코드를 리팩터링 하기 위해 역할과 책임을 다시 나눠본다.

Problem

objc.io 사이트의 Ash Furrow 님이 작성하신 Introduction to MVVM 자료를 인용하였다.

Cocoa MVC에서 활용되는 결합된 역할의 대표 사례인 View controller는 UIKit 어플리케이션에서 주요하게 사용되는 클래스이다. Cocoa MVC를 UIKit 애플리케이션의 실제 클래스 다이어그램 구조로 표현하면 다음과 같다.

Practical Cocoa MVC - objc.io

ViewController는 View 계층을 관리하면서도 Model과 View의 데이터 흐름을 중재하는 Controller 역할을 함께 수행하기 때문에 앱 개발 과정에서 많은 논리들이 ViewController에 배치될 가능성이 높다. 작은 규모의 개발 프로젝트에서는 개발 시간을 단축하기 좋은 방법일 수 있으나 규모가 커질수록 코드를 관리하기 어려울 수 있다.

Solutions

Core Idea

ViewController에 구현된 주요 논리를 추상화할 수 있다. 예를 들어 MVC에서 ViewController는 중재자 Controller의 역할을 하기 때문에 ViewController에는 필연적으로 Model 객체를 관리하는 코드를 갖고 있다. Model의 Controller 객체를 통해 Model을 관리하고 ViewController가 Model Controller에 관리 책임을 위임하는 전략을 통해 ViewController가 데이터를 보여주는 역할에 집중할 수 있도록 개선해 볼 수 있다.

MVVM

MVVM은 MVC와 마찬가지로 View와 Model을 분리해주기 때문에 비슷해 보인다. 다만 어떤 구성요소가 있는지 그리고 어떻게 구성요소 서로가 상호작용하는지 메커니즘에서 미묘한 차이를 보인다.

MVVM Diagram - objc.io

Responsibility

Model

Model은 MVC에서의 Model처럼 어플리케이션의 데이터나 로직을 캡슐화한 역할을 의미한다. 재사용성을 위해 UI와 완전히 독립적인 관계를 갖는다.

View

ViewController는 더이상 Model과 View의 중재자 Controller역할을 하지 않는다. MVVM에서는 사용자 액션 등의 이벤트를 받고 사용자에게 시각적으로 어떻게 보이는지를 관리하는 View의 역할을 담당한다.

ViewModel

ViewModel은 View와 Model의 중재자 역할을 담당한다. 따라서 ViewModel에는 View와 Model 간의 상호작용에 필요한 개념을 추상화하여 메서드나 프로퍼티 혹은 바인딩 메커니즘을 구현하게 된다. 예를 들어 데이터를 포맷팅하는 등의 Presentation 작업을 ViewModel에서 수행하여 View에게 전달해 줌으로써 View 코드를 단순하게 유지할 수 있게 된다.

Communication

MVVM 소통의 기본 규칙은 Model과 View가 반드시 ViewModel을 통해서만 상호작용 하는 것이며 전반적으로 단방향 참조 관계에 기반하여 데이터의 흐름과 호출 관계가 정의되어있다.

View - ViewModel 관계

View는 ViewModel을 소유한다. View에서 사용자 액션 등의 이벤트가 발생하면 ViewModel의 Intent 함수를 호출할 수 있다.

ViewModel은 Model의 변화를 감지하면 View에게 이벤트를 전달한다. 이때, View는 ViewModel의 메서드를 통해 데이터를 받아서 화면을 갱신한다.

ViewModel은 View와 참조 관계가 없기 때문에 바인딩 기술을 활용하게 된다.

ViewModel - Model 관계

ViewModel은 Model을 소유한다. ViewModel은 이벤트의 의도에 맞춰 Model을 수정할 수 있다.

ViewModel은 Model의 변화를 감지할 수 있다. Model 상태가 변동되면 ViewModel에게 상태가 변경되었음을 안내한다.

Model은 ViewModel과 참조 관계가 없기 때문에 바인딩 기술을 활용하게 된다.

Key Point

MVVM은 기존 MVC 아키텍처와 호환된다. MVC에서의 책임을 세부적으로 나눠주어 MVVM 구조로 리팩터링함으로써 View Controller를 가볍게 유지할 수 있게 되었다.

MVVM은 프로젝트를 테스트하기 쉬운 구조로 만드는데 도움 준다. 예를 들어 비즈니스 로직은 단위 테스트, View는 UI 테스트로 구분하여 테스트할 수 있다.

Advanced

Data Binding Technology

앞서 소개한 대로 MVVM은 단방향 참조 관계를 갖는다. Model과 View의 의존성을 최대한 분리하고 싶었기 때문이다. 따라서 Model의 상태가 변할 때 ViewModel을 통해 데이터를 View에 바인딩시키는 과정이 필요하며 다양한 기법을 통해 구현할 수 있다.

전통적인 방식으로는 KVO, Notification Center, Closure, Property Observer 등을 사용하는 방식을 생각해 볼 수 있다.

때로는 비동기 데이터 스트림을 활용한 Reactive Programming 기법을 활용하기도 한다. 대표적으로 Reactive X 혹은 Combine 기술을 생각해볼 수 있다. 함수형 패러다임의 API를 통해 비동기 이벤트를 손쉽게 가공할 수 있기도 하다.

References

Introduction to MVVM - objc.io
Stanford CS193p: MVVM

반응형