[kotlin] Repository Pattern

Boknami·2024년 1월 17일
0

디자인 패턴

목록 보기
2/2

🔍정의

데이터가 로컬에서 가져온건지 아니면 웹API로 가져온건지 관계없이 동일한 인터페이스를 통해 데이터에 접근할 수있게 하는 패턴

🤔Why?

그럼 이 레포지토리 패턴을 왜 사용할까는 생각이 들었다.
패턴을 학습하면서 교수님께 가장 많이 들었던 것이 'coupling 줄이고 Cohesion은 늘려라' 라는 말이었다.

디자인 패턴을 배울수록 디자인 패턴은 정말 결합도, 응집도를 위해서 만들어졌다는 생각이 들 수 밖에 없는 것 같다.

📑 예시를 보자

가장 단순하게 레트로핏 인스턴스를 object로 만들어두고 우리는 서버와 통신을 시작한다.

정말 기본만 구현하기 위해 액티비티에서 바로 레트로핏을 이용해 통신을 시작해서 우리는 응답을 가져왔고 성공적이었다.


그런데 앱의 특성상 우리가 앱에 저장해놓는 데이터가 있을 것이다.
쉽게 생각하자면 우리가 해놓은 다크모드 설정 같은 것들을 로컬DB에 저장한다고 생각하자.

그렇다면 아래 그림과 같이 될 것이다.

결론적으로 이 그림에서는 액티비티가 서버 데이터인지 내부DB 데이터인지 구분해서 생각해야하는 상황이 오는 것이다.

이러한 상황을 타파할 수 있는 것이 레포지토리 패턴이다.

바로 아래에 그림처럼 레포지토리를 그 사이에 두어 할 일을 위임해주는 것이다.


💻 코드로 보는 예시

인터페이스

  • 데이터에 대해 수행하려는 작업을 선언하는 인터페이스를 정의
  • 레포지토리를 구현하는 모든 클래스가 따라야 하는 계약
interface BookRepository {
    suspend fun getAllBooks(): List<Book>
    suspend fun getBookById(bookId: String): Book?
    suspend fun addBook(book: Book)
}

레포지토리 구현(BookRepositoryImpl):

저장소 인터페이스를 구현하는 클래스를 만듭니다. 이 클래스에는 데이터 액세스 작업의 실제 구현이 포함되어 있습니다.

class BookRepositoryImpl : BookRepository {
    override suspend fun getAllBooks(): List<Book> {
        // Implementation to fetch all books from the data source
        // (e.g., database, network)
    }

    override suspend fun getBookById(bookId: String): Book? {
        // Implementation to fetch a specific book by ID
    }

    override suspend fun addBook(book: Book) {
        // Implementation to add a new book to the data source
    }
}

레포지토리를 이용해 데이터 가져오기

  • Activity나 ViewMode에서 레포지토리를 사용하여 데이터와 상호 작용
  • 애플리케이션 로직과 데이터 검색 세부사항을 명확하게 분리
class BookViewModel(private val bookRepository: BookRepository) : ViewModel() {
    // Example function in ViewModel to retrieve all books
    fun getAllBooks(): List<Book> {
        return runBlocking {
            bookRepository.getAllBooks()
        }
    }
}

0개의 댓글