이번주 스터디 그룹의 주제는 디자인 패턴 중 앱 아키텍처 패턴으로, 대표적인 4가지 아키텍처에 대해 살펴보고자 합니다.
🔧 아키텍처 패턴(설계 패턴)이란
사전적 정의로 아키텍처 패턴은 공통적으로 자주 발생하는 문제를 해결하는 재사용 가능한 해결방법입니다.
이는 소프트웨어 아키텍처보다 큰 범주를 가집니다.
과거 UI를 가진 프로그램에서 데이터를 기반으로 화면에 렌더링 할 책임이나, 비즈니스 로직을 아까 말한 책임과 함께 묶는 방법에 대한 정의가 명확하지 않았습니다. 아키텍처 패턴은 이를 해결하기 위해 만들어진 디자인 패턴입니다.
🔧 모바일 앱 4대 아키텍처
아래 4가지는 현대 개발자가 주로 사용하는 아키텍처로, 밑에서 이들의 차이점을 설명하고자 합니다.
- MVC (Model-View-Controller)
- MVP (Model-View-Presenter)
- MVVM (Model-View-ViewModel)
- MVI (Model-View-Intent)
각 디자인 패턴은 공통적으로 두 가지의 구성요소(Component)를 갖고 있습니다.
View - 색상, 모양, 클릭 이벤트 수신 등 화면과 레이아웃을 처리합니다. 이때의 정보는 Model을 기반으로 합니다.
Model - 뷰가 이곳의 데이터에 따라 렌더링하고 작동하게 하려는 비즈니스 로직을 관리합니다. 데이터의 수정, 갱신에 필요한 API(또는 query)를 제공합니다.
이는 물리적으로 독립된 모듈을 갖는 3계층 레이어 구조(3-tier architecture)와 대비하여 볼 수 있습니다.
- Presentation layer는 소프트웨어의 최상위 계층에 위치하며, 사용자에게 보여주는 인터페이스 및 결과를 표시하기 위해 필요한 데이터를 내보내는 다른 계층과 통신합니다. 간단히 설명하면 사용자가 직접 접근할 수 있는 계층입니다.
- Business layer는 Presentation layer와 분리되어 세부적인 처리(비즈니스 로직 등) 기능을 제어합니다. 클라이언트 요청에 대해선 정보를 제공하고, Data layer에게 정보를 요청합니다.
- Data layer는 Data persistence mechanism(DB 서버, 파일 공유)과 이러한 데이터를 노출(API 제공)하는 Data access layer를 포함합니다.
View는 Presentation layer에, Model은 Business layer의 핵심 요소로 의존성이 생김을 통해 알 수 있습니다.
아래의 그림에서는 Data access layer와 Data layer를 같은 것으로 표기하고 있음에 유의해주세요.
🔧 MVC
MVC는 사용자 인터페이스, 데이터 및 비즈니스 로직을 구현하는데 흔히 사용되는 소프트웨어 디자인 패턴입니다.
비즈니스 로직과 UI를 분리하는 "관심사 분리"가 중점으로 이후에 나오는 다른 아키텍처에 큰 영향을 미쳤습니다.
MVC패턴은 아래와 같은 총 3가지가 대표적으로 알려져있습니다.
- Classic MVC
- Passive Model MVC
- Application Model MVC (AM-MVC)
클래식 MVC와 수동적 MVC 모델
1979년에 Trygve Reenskaug로부터 처음 만들어졌으나, Smalltalk-76, Smalltalk-80 언어 등으로 구현되었고, 최근 UI 구성이 복잡해짐에 따라 애플리케이션 MVC모델이 새롭게 탄생하였습니다.
View와 Model은 앞서 설명한 공통 설명과 같습니다.
Controller - 사용자의 입력을 전달받아, Model이 동작하도록 명령합니다.
첫 번째 이미지는 클래식 MVC 모델로 View와 Controller와의 직접적인 통신이 없는 것이 특징이며,
두 번째 수동적 MVC 모델은 Controller가 Model에 상태 변경을 내리는 것은 같으나, Controller가 View에 상태 변경을 알려야 하는 차이점이 있습니다.
Active MVC | Passive MVC | |
공통 로직 | 1. Controller는 사용자로 부터 입력을 받아, Model에게 명령합니다. | |
이후 처리 | 2. Model은 비즈니스 로직을 수행하고, 상태를 변경, 이벤트를 발생시켜 View에 알립니다. 3. View는 Model에 정보를 요청하여 상태를 변경합니다. |
2. Model은 비즈니스 로직을 수행하고, 상태를 변경합니다. 3. Controller는 View에게 상태 변경을 알립니다. 4. View는 Model에 정보를 요청하여 상태를 변경합니다. |
애플리케이션 MVC 모델
이후 UI의 복잡성이 증가함에 따라 Presentation logic(ex. 화면 색상 변경 또는 뷰 상태 변화)를 구현할 곳이 필요해졌고, Application model이 추가된 애플리케이션 MVC 모델이 탄생하였습니다.
이러한 특징들 외에도 MVC는 아래와 같은 공통적인 특징을 갖고 있습니다.
- View와 Controller는 Model에 대한 의존성을 갖고 있다.
- Model은 다른 것들로부터 완전히 독립적이다.
- 각 View는 하나의 Controller를 반드시 가져야 하지만, 하나의 Controller는 여러 개의 View에 공유될 수 있다.
안드로이드의 경우
하지만! 안드로이드의 경우 위의 모델으로는 구현할 수 없는 문제가 있습니다.
이는 View와 Controller의 역할, 즉 UI와 사용자의 입력을 받는 Controller의 역할을 위젯이 위임받아 액티비티(Activity)/프래그먼트(Fragment)에서 처리가 가능해졌기 때문입니다.
class MainActivity: Activity() {
...
button.setOnClickListener {
// event logic
}
...
}
따라서 아래와 같은 플로우차트를 가집니다.
🔧 MVP
MVC의 가장 큰 문제는 View와 Model 간의 의존성과, 시대가 지남에 따라 Controller의 역할이 이미 위젯에 포함되어 불필요해짐에 있습니다.
MVP는 이를 개선하고자 사용자의 입력을 View에서 처리하도록 하고, 불필요한 Controller 대신 Presenter 컴포넌트가 추가된 구조입니다.
Presenter - 사용자의 입력을 전달받은 View로부터 호출을 받고, Model에게 비즈니스 로직을 수행 및 데이터를 수신받으며, 다시 View에게 전달하여 UI를 업데이트합니다.
MVP는 대표적으로 두 가지로 나뉘며,
Supervising controller MVP 모델에서는 View와 Model간의 Observer 패턴을 적용하여, Model의 상태가 변경되면 View가 업데이트되는 차이점이 있습니다.
넷상에서는 대체로 Passive view를 MVP로 표현합니다.
🔧 MVVM
프로그래밍 패러다임이 반응형 프로그래밍(Reactive Programming)으로 변화함에 따라, UI를 가진 프로그램에서 변경사항을 관찰(Observing)하고 개별적으로 문제를 해결할 수 있다는 것이 증명됐습니다.
2005년 Microsoft의 WPF와 Silverlight 설계자 멤버인 John Gossman은 MVVM을 발표했습니다.
이 모델은 Controller가 ViewModel로 대체된 Presentation logic과 Business logic을 분리하는 또 다른 모델입니다.
이러한 패턴인 이유는 앞서 MVP 모델과 마찬가지로 현대 GUI 프로그램 개발에 Controller의 책임(키보드와 같은 입력장치와의 상호 작용)은 View에서 담당하기 때문입니다.
ViewModel - View는 ViewModel의 데이터를 바인딩하여 UI를 업데이트하고, ViewModel은 Model을 바인딩하여 데이터를 가져옵니다.
아래는 주요 특징들입니다.
- View는 ViewModel을 알고 있지만, ViewModel은 View에 대해 알지 못합니다.
마찬가지로 ViewModel은 Model을 알지만, Model은 ViewModel의 존재를 알지 못합니다.(참조가 없습니다) - ViewModel의 데이터를 트리거하여 View를 자동으로 업데이트하기 위해 Observer 패턴 구현 라이브러리(RxJava, Flow)를 사용합니다.
- View를 업데이트하는 트리거 방법이 없습니다.(외부에서 View의 업데이트를 호출할 수 없습니다.)
안드로이드의 경우
Xml 방식의 UI 구성일 경우 Data binding(데이터 바인딩)을 통해 ViewModel의 객체 변화를 UI에 반영하고 사용자의 입력을 ViewModel에 전달할 수 있습니다.
Compose 방식의 경우 Flow, LiveData 등을 활용하여 Composable 내에서 데이터를 수집 및 UI에 반영하고, 사용자의 입력 등의 이벤트가 발생하면 ViewModel의 메서드를 호출합니다.
🔧 MVI
MVVM 패턴의 문제는, 상태 관리와 부수 효과(Side Effect)라는 점에 있습니다.
이는 데이터를 개별적으로 관리함에 있어, 복잡적으로 묶여있는 함수들 간의 관계에 예상치 못한 결과가 나올 수 있기 때문에 발생합니다. (Ex. 여러 개의 데이터를 화면상에 표현해야 할 때, 일부분의 데이터가 누락/오류 등이 발생했을 때 표시해야 하는 각 상황별 UI를 생각할 수 있습니다.)
MVI 패턴은 유한 상태 머신(finite state machine)을 기반으로 하며, Intent의 개념이 추가됩니다.
Intent - 사용자 또는 앱의 상태를 바꾸기 위해 보내는 요청, 이벤트 전달을 위한 객체
Model - 앱 UI의 상태와 데이터를 갖는 단일 불변 객체
사용자의 입력이나 이벤트를 Intent로 묶어 Model에 전달하여, 데이터를 갱신하고, 다시 View에 표시하는 것으로 볼 수 있습니다.
안드로이드의 경우
시간이 걸리는 API 통신, Background 작업이나, I/O 작업 등으로 인해 Intent의 전달만으로 Model을 호출하여 View에 보여주는 단순한 구조가 성립하기 힘들 수 있습니다.
따라서 이러한 Side Effect를 관리하는 영역이 존재하며, 주로 ViewModel과 결합된 모델을 사용합니다.
MVI 패턴은 직접 구현할 수도 있으나, Orbit이나 MVICore와 같은 라이브러리를 활용할 수 있습니다.
마치며
각 아키텍처별 차이점에 대해 간략히 만 알고 있었는데 이번 기회로 각 아키텍처가 나오게 된 계기와 세부적인 특징까지 학습해 보았습니다.
후에 코드 예시를 들며 직접 작성해 보도록 하겠습니다.
감사합니다.
- 참조
- https://en.wikipedia.org/wiki/Design_Patterns
- https://blog.naver.com/jukrang/221597910488
- https://www.geeksforgeeks.org/mvc-model-view-controller-architecture-pattern-in-android-with-example/?ref=lbp
ⓒ 굿햄 2022. daryeou@gmail.com all rights reserved.
'디자인패턴 > Clean Architecture' 카테고리의 다른 글
클린 아키텍처(Clean Architecture) 개념 및 원칙 (0) | 2023.02.01 |
---|
댓글