State Management를 배워야 하는 이유
- 최초 개발을 빠르게 하기 위해:
- 상태 관리(State Management)를 통해 앱의 복잡한 상태 전환을 쉽게 다룰 수 있습니다. 이는 초기 개발 속도를 높여줍니다.
- 상태 관리 도구들은 코드의 재사용성을 높이고, 개발자가 복잡한 상태 전환 로직을 쉽게 구현할 수 있도록 돕습니다.
- 앱 스펙이 수정될 때 필요한 부분을 빠르게 찾고 수정하기 위해:
- 앱의 상태 관리를 체계적으로 하면, 특정 기능이나 UI의 변경 사항이 어디에 영향을 미치는지 쉽게 파악할 수 있습니다.
- 상태 관리 도구들은 상태 변화를 추적하고 관리하는 데 도움을 줌으로써, 유지보수와 기능 추가가 용이해집니다.
Android와 iOS의 개발 패턴
- MVC (Model View Controller):
- 모델(Model): 애플리케이션의 데이터 구조를 관리
- 뷰(View): 사용자 인터페이스 요소를 관리
- 컨트롤러(Controller): 사용자 입력을 처리하고 모델과 뷰를 업데이트
- MVP (Model View Presenter):
- 모델(Model): 데이터와 비즈니스 로직을 관리
- 뷰(View): UI를 담당, 사용자 인터페이스 요소
- 프리젠터(Presenter): 뷰와 모델 사이의 인터랙션을 처리하고 뷰를 업데이트
- MVI (Model View Intent):
- 모델(Model): 상태를 정의
- 뷰(View): 상태를 기반으로 UI를 렌더링
- 인텐트(Intent): 사용자의 의도를 캡처하고 모델에 반영
- VIPER (View Interactor Presenter Entity Router):
- 뷰(View): UI 요소
- 인터랙터(Interactor): 비즈니스 로직 처리
- 프리젠터(Presenter): 뷰와 인터랙터 간의 데이터 교환을 관리
- 엔티티(Entity): 데이터 구조 정의
- 라우터(Router): 화면 전환 관리
- MVVM (Model View ViewModel):
- 모델(Model): 애플리케이션의 데이터와 비즈니스 로직
- 뷰(View): 사용자 인터페이스 요소
- 뷰모델(ViewModel): 모델과 뷰 사이의 데이터 바인딩을 처리
전통적인 패턴의 문제점
- MVC:
- 원래 작은 컴포넌트를 위한 설계로, 현대 애플리케이션의 복잡성을 다루기 어려움.
- 데이터 관찰 기능이 포함되어 있지만, 전체 애플리케이션의 상태를 관리하기에는 부족함.
- MVP:
- View와 Presenter의 분리를 통해 코드 관리는 용이하지만, Presenter의 로직이 복잡해질 수 있음.
- Presenter가 많은 역할을 하게 되어 코드가 방대해지고 유지보수가 어려워질 수 있음.
- MVVM:
- 상태 관리를 도입하여 이를 개선했으나, ViewModel의 역할이 커지면서 복잡성이 증가.
- 데이터 바인딩 과정에서 발생할 수 있는 문제를 해결하는 데 어려움이 있을 수 있음.
- 최종적으로 선언형 UI:
- 선언형 UI가 등장하면서 View의 패턴 구조 논의는 필요 없어짐.
- 대신 데이터와 상태 관리가 더욱 중요해짐.
State Management 구조의 종류
- Scoped Model:
- 특정 스코프 화면이 사라지면 자동으로 메모리 해제가 됨.
- 구별자 없이 상위 데이터 참조가 가능하여, 데이터의 전역 접근이 용이함.
- Static Model:
- 메모리 관리를 개발자가 직접 해야 함.
- 항상 구별자가 필요하여, 데이터 접근 시 매번 구별자를 사용해야 함.
- 모든 코드에서 상태 접근 및 수정이 가능하며, 구현이 상대적으로 쉬움.
각 방법의 장단점
- Scoped Model:
- 장점:
- 메모리 자동 해제: 화면이 사라지면 메모리가 자동으로 해제되어 메모리 관리가 용이함.
- 상위 데이터 참조 용이: 구별자 없이 데이터 참조가 가능하여 코드의 간결성을 유지할 수 있음.
- 단점:
- 스코프에 한정되어 있으므로, 전역 상태 관리가 필요할 경우에는 적합하지 않을 수 있음.
- Static Model:
- 장점:
- 모든 코드에서 상태 접근 가능: 상태를 전역적으로 관리할 수 있어, 어디서든 상태에 접근하고 수정할 수 있음.
- 구현이 쉬움: 구조가 간단하여 초보자도 쉽게 구현할 수 있음.
- 단점:
- 메모리 관리 필요: 개발자가 직접 메모리를 관리해야 하므로, 메모리 누수 등의 문제가 발생할 수 있음.
- 구별자 필요: 데이터 접근 시마다 구별자를 사용해야 하므로 코드가 번잡해질 수 있음.
좋은 앱의 아키텍처와 상태 관리 방법를 고민하는 이유
- 쉬운 개발:
- 구조 파악이 쉬움.
- 코드 작성 양 감소.
- 가독성 향상.
- 안정성:
- 성능:
- 500만 연산 미만은 성능에 큰 영향을 미치지 않음.
- 확장성:
- 추가 기능 제공:
아키텍처 & 상태 관리
- 맞고 틀리고의 정답은 없으며, 단지 차이점만 존재함.
- 어떤 것이 좋은지 알아보는 데 너무 많은 시간을 소비하는 것은 낭비일 수 있음.
- 직접 경험해보는 것을 추천함.
Bloc, Riverpod, GetX 패키지 차이점 비교
GetX
- 접근 방식:
Get.find()
를 사용하여 컨트롤러에 접근.
- State 보관 방법:
GetxController
안에 직접 필드로 보관.
- 장점: 접근성이 좋고, 구현이 간단함.
- 단점: 복잡한 애플리케이션에서는 구조적으로 어려움을 겪을 수 있음.
- 부가 기능: 뷰 없이 다른 State끼리 연결하기 위해 별도 구현 필요.
Bloc
- 접근 방식:
context.read
를 사용하여 Bloc에 접근.
- State 보관 방법:
Cubit
, Bloc
마다 하나의 State 객체만 관리.
- 장점: 구조적이고, 기능이 많아 확장성 좋음.
- 단점: 구현이 복잡하며,
copyWith
함수와 같은 추가적인 코드가 필요함.
- 부가 기능: 다른 State와 연결 시 이벤트를 발생시켜 전달. 하지만 공식 가이드에서는 이를 권장하지 않음.
Riverpod
- 접근 방식:
ref.read
를 사용하여 StateNotifier에 접근.
- State 보관 방법:
StateNotifier
안에 하나의 State 객체만 보관 가능.
- 장점: 가장 직관적인 방법으로 서로 참조 및 관찰 가능.
- 단점: 사용법이 다소 어렵고, 초기 설정이 필요함.
- 부가 기능: 뷰 없이 다른 State끼리 연결하기에 가장 적합하며, 별도의 watch를 통해 관찰 및 통제 가능.