앱 아키텍처 정보 > 일반 아키텍처 원칙

John·2023년 6월 21일
0
post-thumbnail

이 글은..

공식 문서를 읽은 후기입니다.
안드로이드 아키텍처로 Clean Architecture 는 이제 유명하고, 실무에서도 많이 다뤄집니다.
Clean Architecture 에 대한 자세한 이야기는 다음에 자세히 다뤄보고,
오늘은 Android 진영에서는 어떤 아키텍처를 권하는지 알아보려고 합니다.

일반 아키텍처 원칙

관심사 분리(SRP)

SOLID 원칙 중 하나인, SRP 원칙을 가장 먼저 이야기합니다.
당연하게도, Activity, Fragment 등 UI 와 밀접한 컴포넌트의 책임을 현저히 줄이라고 권합니다.
저도 처음 안드로이드를 개발할 때는, 비대한 Activity 를 자주 만들었던 기억이 있네요.
Clean Architecture 에서도 Android Platform 은 가장 바깥쪽 원에 자리잡죠.
플랫폼에 종속적인 부분만 Android Component 에 위치시켜야겠습니다.

Activity 와 Fragment 에서는 반드시 이 클래스 내에서 해야하는 일만 맡기고,
그 외의 일들은 다른 곳으로 위임해야합니다.

데이터 모델에서 UI 도출하기(Drive UI from data models)

타이틀의 한글 번역이 다소 생소하게 느껴지네요.

Data models represent the data of an app.

즉, 앱에서 사용하는 데이터를 잘 표현한 것을 Data model로 정의합니다.

They're independent from the UI elements and other components in your app.
They are not tied to the UI and app component lifecycle.

Data model은 UI 요소, 또는 그 외의 다른 어떤 컴포넌트와도 독립적이어야하고
Activity 또는 Fragment 등 어떤 컴포넌트의 라이프사이클과도 관계가 없어야합니다.

이런 데이터를 '지속적인 모델(Persistent models)' 이라고 표현합니다.

지속적인 모델을 사용하는 장점으로 'OS 차원에서 프로세스가 죽어도 보존이 가능'하고, '오프라인 모드에서도 정상 동작하는 점'을 이야기해요.

즉, 화면에 랜더링되는 데이터는 원격에서 가져오든, 로컬에서 가져오든, 우리가 직접 핸들링할 수 있는 저장소에서 가져와서 사용해야한다는 점이 요지인 것 같아요.
다시 말해, 데이터 모델은 UI 나 Life-cycle 을 갖는 그 어떠한 Android Component 와 철저하게 독립적으로 관리되어야 하죠.

단적인 예를 들면,
우리가 (편의상) Activity 클래스 내에 멤버변수를 선언하고, 서비스가 표현하고자하는 데이터를 들고 있게 한다고 가정했을 때, 앱이 Background 에서 정리된 후에 재실행되었다고 가정할 때, 우리가 이 멤버변수를 화면 랜더링에 활용 중이었다면 문제가 생기게 되겠죠.
'데이터 모델에서 UI 도출하기' 는 이런 부분을 이야기 하는 것 같습니다.

화면에 표시되는 데이터는 모두 (잘 만들어지고, 관리되는) Datasource 를 통해서 가져오자

단일 소스 저장소(SSOT, Single Source of Truth)

데이터를 가져오는 곳, 데이터의 주인, 데이터를 제공해주고 변경할 수 있는 곳은 하나여야 합니다.

대화방의 메시지 목록을 보여주는 메신저 서비스를 생각해봅시다.
일반적인 상황, 네트워크가 연결된 상황에서는 대화방에 진입할 때 원격에서 최신 메시지들을 가져와서 보여주겠죠.
그런데 만약, 네트워크가 단절된 상황에서 대화방에 진입하면?
아마도, 로컬 저장소에 있는 메시지들을 가져와서 일단 보여줄거에요.

if (network is connected)
  fetch messages from remote datasource
else 
  get messages from local datasource

코드 어딘가에 이런 로직이 들어가겠죠.
그런데, SSOT 는 이렇게 datasource 를 이원화하지 않는 것을 권합니다.
이원화를 하면 위처럼 결국 우리가 '로직을 통해 관리'를 해줘야 하기 때문입니다.

SSOT 는 remote datasource 에서 받은 메시지들은 local datasource 에 저장해두고,
사용자에게는 항상 local datasource 에서만 메시지들을 가져오도록 권합니다. (단적인 예)
즉, 아키텍처 관점에서 하나의 데이터는 하나의 datasource 에서 가져오도록 제한을 하면 좋겠다가 포인트입니다.
그 하나의 datasource 가 대신, 잘 관리되어야겠죠.
이 부분은 Repository 의 책임으로 볼 수 있을 것 같습니다.
즉, Repository 는 로컬 저장소를 조회할 수 있는 메소드를 열어두고, 리모트 저장소를 조회할 수 있는 메소드는 닫아두도록 권하는 것 같아요.

저도 여지껏, SSOT 보다는 전자의 방식으로 local, remote datasource 를 각각 필요에 따라 가져올 수 있도록 모두 열어두어왔는데, 한번 실무에 적용할 때 어떤 고민 포인트가 생길지 고민해봐야겠습니다.

단방향 데이터 흐름(Unidirectional Data Flow)

하위 레벨(UI 레이어)에서 발생한 이벤트는 쭉쭉 올라가서, SSOT, 즉 데이터소스에 다다르거나,
데이터소스에서 UI 레이어까지 데이터가 내려오는, 이런 단방향 흐름을 이야기합니다.
당연히 데이터는 단방향으로 흘러야 실수도 적고, 디버깅도 쉽겠죠.

반대의 케이스를 예로 들면 Bidirectional 일 텐데, 보통은 단방향 흐름이 너무 일반적이라 잘 상상이 안가긴 합니다. 대부분의 프로젝트를 Clean Architecture 기반으로 진행을 해서, 데이터의 단방향 흐름은 너무나 당연하게 느껴지네요.

단방향 데이터 흐름은 MVI 패턴에서도 강조하는 부분이에요.
전체적인 아키텍처의 단방향성, Presentation 레이어에 MVI 패턴을 통한 단방향성 모두,
장점은 의존성이 명확히 구분되고, 데이터 흐름을 이해하기 쉽고, 결국 유지보수에 도움을 준다고 볼 수 있겠습니다.

원문

https://developer.android.com/topic/architecture?hl=ko

profile
아직 멀었습니다

0개의 댓글