참고하여 공부하고 있는 android architecture sample 의 데이터 저장 및 관리 부분이다. 안드로이드에서 데이터 저장 및 관리는 어떻게 수행되는지 파악하기 위해 각 파일에서 어떠한 역할이 수행되는지 알아보았다. 또한 그 과정에서 처음 보는 개념 및 궁금증에 대해 따로 정리해두었다.
각 파일 별 역할
- DefaultTaskRepository.kt:
- 기본 작업 리포지토리 클래스를 정의한다.
- TaskRepository 인터페이스를 구현한다.
- 로컬 데이터 소스(localDataSource)와 네트워크 데이터 소스(networkDataSource)를 사용하여 작업(Task) 데이터를 관리한다.
- ModelMappingExt.kt:
- 이모델 간 변환을 위한 확장 함수를 정의한다. 데이터 모델 간의 변환 또는 매핑을 위한 코드가 포함된다.
- Task.kt:
- 작업(Task) 데이터 모델을 정의한다.
- TaskRepository.kt:
- 작업(Task) 관련 데이터를 관리하는 리포지토리 인터페이스를 정의한다.
- source/local 디렉토리:
- 이 디렉토리에는 로컬 데이터 소스 관련 파일들이 포함된다.
- LocalTask.kt: 로컬 작업 데이터 모델을 정의한다.
- TaskDao.kt: 작업 데이터베이스와 상호작용하기 위한 DAO(Data Access Object)를 정의한다.
- ToDoDatabase.kt: 작업 데이터베이스를 생성 및 관리하는 코드가 포함된다. (RoomDatabase 클래스 상속)
- source/network 디렉토리:
- 이 디렉토리에는 네트워크 데이터 소스 관련 파일들이 포함된다.
- NetworkDataSource.kt: 네트워크 데이터를 가져오는 데 사용되는 데이터 소스 인터페이스를 정의한다.
- NetworkTask.kt: 네트워크에서 가져온 작업 데이터 모델을 정의한다.
- TaskNetworkDataSource.kt: 네트워크 데이터 소스와 상호작용하는 코드를 구현한다.
궁금증
1. TaskRepository interface 를 쓰는 이유
이는 interface 를 쓰는 이유와 같다. 간단하게 정리하면 좋을 것 같다.
- 다형성 (Polymorphysim) 및 의존성 역전 원칙 (Dependency Inversion Principle) 적용
하나의 인터페이스 타입(e.g TaskRepository interface)에 여러 구현체(e.g DefaultTaskRepository .. )가 있다. 따라서 고수준의 모듈(주로 어플리케이션)이 저수준의 모듈(구현체)에 직접적으로 의존하는 것이 아닌 인터페이스에 의존할 수 있다. - 테스트 용이성
인터페이스를 사용하면 테스트를 위해 mock 객체를 만드는 것이 쉽다. - 제어의 역전(IoC, Inversion of Control)
코드의 제어를 외부에서 가능하게 한다.
의존성 주입과 같은 패턴을 적용하여 객체 생성 및 관리를 외부에서 수행할 수 있다. - 유지보수와 확장성
인터페이스를 사용하면 새로운 구현체를 추가하거나 기존 구현체를 교체하는 작업이 간단해지므로 유지보수와 확장성을 향상시킨다. - 협업과 모듈화
여러 개발자가 작업할 때 인터페이스를 사용하면 각자의 모듈 또는 컴포넌트를 독립적으로 개발하고 연결할 수 있으므로 협업과 모듈화를 용이하게 한다.
2. 처음 보는 문법들
- @singleton, @Inject
@Singleton
class DefaultTaskRepository @Inject constructor(
private val networkDataSource: NetworkDataSource,
private val localDataSource: TaskDao,
@DefaultDispatcher private val dispatcher: CoroutineDispatcher,
@ApplicationScope private val scope: CoroutineScope,
) : TaskRepository {
해당 클래스는 single ton 으로 관리되며 외부 의존성 주입 프레임워크에 의해 의존성이 주입(inject)된다는 의미이다.
- Coroutine
비동기 프로그래밍 및 병렬 처리를 위한 Kotlin 언어의 핵심 기능이다. 추후에 더 알아볼 가치가 있는 개념이다. - suspend
비동기 작업을 수행하기 위해 사용된다. - Flow
Kotlin에서 비동기 및 데이터 스트림을 처리하기 위한 새로운 비동기 프로그래밍 기능이다. - withContext
Kotlin의 코루틴(coroutine)을 사용할 때 사용되는 함수 중 하나로, 다른 코루틴 디스패처(스레드 또는 스레드 풀)에서 코드 블록을 실행할 수 있게 해주는 함수이다. withContext를 사용하면 비동기 작업을 수행할 때 다른 스레드에서 실행되도록 지정할 수 있다. 안드로이드 앱 개발에서 네트워크 요청 또는 파일 I/O와 같은 비동기 작업을 수행할 때 withContext를 사용하여 백그라운드 스레드에서 실행할 수 있다. 이렇게 하면 메인 스레드(UI 스레드)에서 작업을 수행하는 동안 앱이 응답하지 않는 문제를 피할 수 있다. - mutex
일반적인 Mutex 와 동일하다. 여러 스레드가 데이터 경쟁 상태에 있을 때, 한 번에 하나의 스레드만 접근할 수 있는 임계 영역(critical section)을 생성한다.
'Application > Android Kotlin' 카테고리의 다른 글
[Android] Coroutine 예시 (0) | 2023.12.28 |
---|---|
[Android] 4대 컴퍼넌트 (1) | 2023.12.27 |
[Kotlin] view binding 코드 해석 (var, val, lateinit, nullable) (1) | 2023.12.21 |
[Android] Activity 와 Fragment 의 차이 (0) | 2023.12.20 |
[Android] quick-start android (AndroidManifest.xml 분석) (0) | 2023.12.19 |