Architecture - Data Layer

염준우·2022년 9월 22일
0

MAD SKILLS

목록 보기
1/1
post-thumbnail

먼저 얘기를 나눌 것은 설계를 하는 과정에서 어떻게 보면 가장 중요한 역할을 지니고 있는 데이터 레이어를 보려고 한다.

What is Data Layer?

데이터 레이어란, 애플리케이션의 데이터를 가지고 있거나, 비즈니스 로직을 처리하는 부분들을 담당하는 레이어로 이루어져 있다.

여기서 비즈니스 로직이란 ?? 애플리케이션의 데이터들이 생성되고, 저장되는 로직들 중 변경되지 않을 부분들을 결정하는 것이다.

Data Layer 구성 요소

Repository : 0개, 1개, 혹은 그 이상의 데이터 소스들과 결합하여 상호작용하는 클래스
애플리케이션의 모든 레이어에서 데이터 레이어와 연결시켜주는 역할을 진행한다.
데이터를 보여주고, 데이터의 변화들을 한곳으로 모아주는 작업을 하며, 여러개의 Data Source 에서 발생되는 충돌을 해결하고, 그 충돌을 해결하면서 중요한 비즈니스 로직들은 지속시킨다.
Data Source : 이름과 같이 네트워크, 로컬 데이터베이스, 혹은 메모리에서 직접적으로 데이터를 사용하는 클래스
Data Source 에서는, 클래스 하나당 단 하나의 데이터와만 일을 진행해야 한다. ex. ( RemoteArticleDataSource, LocalUsersDataSource .. etc )
Repository 작성 방법

class MovleRepsitory(...) { }
 
class PaymentsRepository(...) { }

이렇게 하나의 아이템 별로 하나의 리포지토리를 생성하여, 리포지토리가 하나의 아이템에 대해서만 관장할 수 있게끔 진행한다.

리포지토리들은 여려개의 다른 DataSource 들을 합칠 수 있고, 그 합치는 것에 대한 충돌 자체도 이 리포지토리에서 해결을 진행해야 한다.

만약 로컬 DB 와 서버에서 내려오는 값들과의 충돌이 있다고 가정해보자. 그렇게 되면, 리포지토리에서 그 두개의 충돌을 막는것을 지원해주면 된다.

애플리케이션의 모든 레이어에서는 직접적으로 Data Source 와 연결될 수 없다. → 그 뜻은 DataSource 와 연결하려면 무조건 리포지토리를 거쳐야만 가능하다는 것이다.

리포지토리의 가장 보편적인 패턴은, One-shot call 로, CRUD 와 같은 데이터와 연결되는 것을 단 한번만 부르는 패턴을 말한다.

CRUD: Create, Read, Update, Delete 의 약자로, 컴퓨터의 소프트웨어가 가지는 기본인 데이터 처리 과정을 일컫는 말이다.

Source Of Truth

하나의 리포지토리에서 여러개의 데이터 소스를 관리하는 것은 약간 까다로울 수 있다. 그것을 방지하기 위하여 리포지토리를 사용하게 되면, 다른 레이어에서 필요한 것이 무엇인지 알 수 있고, 일관된 상태를 제공할 수 있게 된다.


// LocalDataSource
LocalNewsDataSource(news: Dao) {
    suspend fun fetch(): List<Article> { ... }
    suspend fun update(article: List<Article>) { ... }
}
 
// RemoteDataSource
RemoteNewsDataSource(api: API) {
    suspend fun fetch(): List<Article> { ... }
}

예를 들어, 위와 같이 두개의 DataSource 가 있고, 로컬에서는 Room DB 를 이용하여, Fetch 와 Update 를 진행하고 있고, Remote 에서는 ApiClient 를 이용하여 Fetch 만 진행을 하고 있다.

// Repository

class NewsRepository(
    val localNewsDataSource: LocalNewsDataSource,
    val remoteNewsDataSource: RemoteNewsDataSource
) {
    suspend fun fetchNews() : List<Article> {
        try {
            val news = remoteNewsDataSource.fetchNews()
            localNewsDataSource.updateNews(news)
        } catch (exception: RemoteDataSourceNotAvailableException) {
            Log.d("NewsRepository", "Connection failed, using local data source")
        }
        return localNewsDataSource.fetchNews()
    }
}

참조 : https://www.youtube.com/watch?v=r5AseKQh2ZE

profile
항상 새로움을 추구하는 안드로이드 개발자입니다! 🏆

0개의 댓글