Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 추상팩토리패턴
- Singleton
- 디자인패턴
- 싱글톤
- r
- 빌터패턴
- 팩토리 메소드
- Observer Pattern
- Abstract Factory
- compose
- builderPattern
- 프로토타입 패턴
- 코틀린
- El
- 옵저버 패턴
- 추상 팩토리
- ㅋㅁ
- factory method
- ㅓ
- 디자인패턴 #
- Design Pattern
- Kotlin
- F
- 안드로이드 디자인시스템
- designPattern
- material3
- android designsystem
- PrototypePattern
- 함수형프로그래밍
- Functional Programming
Archives
- Today
- Total
오늘도 더 나은 코드를 작성하였습니까?
Now In Android를 분석하자 (Core 모듈의 구조2) 본문
레벨 1 모듈들의 공통적인 설계 철학: "기술의 캡슐화"
- core:database: 로컬 데이터베이스(Room) 관리.
- core:network: 원격 서버(API) 통신 관리.
- core:datastore: 사용자 설정 등 간단한 데이터(DataStore) 관리.
- core:notifications: 시스템 로컬 알림 생성 및 게시.
- core:testing: 공통 테스트 유틸리티 및 도구 제공.
core:ui
- 비유: "조립식 가구 제작소 (Pre-fabricated Furniture Workshop)"
- 역할: 레벨 0의 core:designsystem(나사, 나무판자, 페인트)과 core:model(설계도)을 가져다가, 앱 전체에서 재사용할 수 있는 의미 있는 UI 조립품을 만듭니다. designsystem이 원자적인 컴포넌트라면, ui는 이것들을 조합한 복합적인 컴포넌트입니다.
- 주요 내용물:
- NewsResourceCard.kt: 뉴스 기사 하나를 보여주는 카드 UI. 내부적으로 designsystem의 텍스트 스타일, 아이콘, 색상 등을 사용하고, model의 NewsResource 데이터를 받아 화면에 표시합니다.
- TopicChip.kt: 주제를 선택하거나 표시하는 칩(Chip) UI.
- NiaTopAppBar.kt: 앱의 공통 상단 앱 바.
- 의존성: core:designsystem, core:model
- 왜 레벨 1인가?
- 이 모듈은 데이터를 '어떻게 예쁘게 보여줄지'에 대한 책임만 집니다. 이 데이터가 어디서 오는지(core:data), 이 카드를 클릭했을 때 어떤 화면으로 이동할지(feature)에 대해서는 전혀 알지 못합니다.
core:database
- 비유: "정보 보관소(Information Archives & Librarian)"
- 역활: 정보 보관소는 core:data (데이터 계층의 주요 부분) 모듈의 지시에 따라, 실제 데이터를 효율적으로 보관하고, 관리하고, 필요할 때 찾아주는 역할을 합니다. 마치 사서가 도서관의 책(데이터)을 분류하고, 대출/반납을 처리하며, 요청에 따라 정확한 책을 찾아주는 것과 같습니다. 이 보관소는 책(데이터)이 물리적으로 어떻게 저장되는지(파일 시스템, 특정 데이터베이스 엔진)의 세부 사항을 직접 구현합니다
- core:database는 앱의 로컬 데이터 영속성(Persistence)을 담당하는 코어 모듈입니다.
- core:data 모듈에서 정의된 LocalDataSource 인터페이스의 구현체를 제공하거나, Repository 구현체에 로컬 데이터 접근 기능을 직접 제공합니다.
- 데이터베이스 스키마 정의, DAO(Data Access Object) 구현, 데이터 마이그레이션 처리 등을 수행합니다.
- 데이터베이스 엔티티를 정의하며, 이 엔티티들은 core:data 모듈 내에서 core:domain의 엔티티로 변환됩니다.
- 로컬 데이터 저장 및 관리에 대한 구체적인 기술적 책임을 집니다.
- 주요 내용물 (예시):
- NiaDatabase.kt: Room Database 클래스 정의 (데이터베이스 버전, 엔티티 목록, DAO 목록 명시).
- NewsResourceDao.kt: NewsResource와 관련된 데이터베이스 작업을 정의하는 DAO 인터페이스 및 구현 (삽입, 조회, 업데이트, 삭제 쿼리).
- TopicDao.kt: Topic과 관련된 DAO 인터페이스 및 구현.
- UserNewsResourceFtsEntity.kt: Full-Text Search (전문 검색)를 위한 엔티티 정의.
- DatabaseModule.kt: Dagger Hilt 등을 사용하여 데이터베이스 인스턴스 및 DAO를 제공하는 모듈.
- 왜 레벨 1인가?
- core:data (Level 2) 모듈이 이 Repository 인터페이스를 구현하며, 이 구현 내부에서 데이터를 가져오는 원천으로 core:database (로컬), core:datastore와 core:network (원격)를 활용합니다.
- core:database는 core:data 모듈이 core:domain의 요구사항을 충족시키기 위한 구체적인 로컬 데이터 소스 구현체 역할을 합니다. 즉, core:data 모듈의 내부적인 로컬 데이터 제공 메커니즘인 셈입니다.
core:datastore
- 비유: "세심한 개인 비서 & 작은 금고 (Meticulous Personal Assistant & Small Safe)"
- 세심한 개인 비서 (core:datastore)는 core:data 모듈(정보를 얻어오는 주체)의 지시를 받아, 특정 형태의 설정 값이나 사용자 선호도 같은 작은 데이터를 안전하고 효율적으로 저장하고 관리하는 역할을 합니다. 마치 비서가 주인의 중요하지만 크지 않은 문서(데이터)를 정리하여 작은 금고(DataStore)에 보관하고, 필요할 때 정확히 찾아주는 것과 같습니다. 이 비서는 데이터가 파일 시스템에 어떻게 기록되는지(직렬화/역직렬화) 등 기술적인 세부 사항을 직접 처리합니다.
- 역할:
- core:datastore는 앱의 로컬 데이터 영속성 메커니즘 중 하나로, 주로 사용자 설정, 선호도, 작은 캐시 데이터 등 키-값 쌍 형태의 데이터를 비동기적으로, 안전하게 영속화하는 코어 모듈입니다.
- core:data 모듈에서 정의된 LocalDataSource 인터페이스의 구현체를 제공하거나, Repository 구현체에 직접 로컬 데이터 접근 기능을 제공합니다.
- Jetpack DataStore 라이브러리(Preferences DataStore 또는 Proto DataStore)와 같은 특정 기술을 사용하여 데이터를 저장하고 검색하는 로직을 구현합니다.
- 데이터 직렬화/역직렬화 로직을 포함할 수 있습니다.
- 주요 내용물:
- UserPreferencesDataSource.kt: 사용자 선호도(테마 설정, 알림 설정 등)를 저장하고 관리하는 DataStore 기반 데이터 소스.
- NiaPreferences.kt / NiaPreferences.proto: Proto DataStore를 사용할 경우, 저장될 데이터의 스키마를 정의하는 Kotlin/Java 클래스 또는 .proto 파일.
- DataStoreModule.kt: Dagger Hilt 등을 사용하여 DataStore 인스턴스 및 관련 데이터 소스를 제공하는 모듈.
- UserPreferencesSerializer.kt: Proto DataStore를 사용할 경우, 데이터를 직렬화/역직렬화하는 로직.
- 왜 레벨 1인가?
- core:datastore는 core:data 모듈과 함께 core:domain의 요구사항을 충족시키기 위한 데이터 제공 역할을 수행합니다.
- core:datastore 모듈을 레벨 1로 분류하는 것은, Level 0 (core:model, core:common) 바로 바깥에 위치하는 주요 아키텍처 계층으로 보고, 그 안에서 core:datastore가 데이터 소스의 한 종류로서 핵심적인 역할을 수행한다고 해석
core:network
- 비유: "해외 특파원 및 통역사 (Foreign Correspondent & Interpreter)"
- 역할: Ktor/Retrofit을 사용하여 원격 서버와 통신하는 모든 책임을 집니다. API 엔드포인트를 정의하고, 네트워크 요청을 보내며, 서버로부터 받은 응답(JSON)을 앱이 이해할 수 있는 객체(DTO)로 파싱합니다.
- 주요 내용물:
- NiaNetworkDataSource.kt: getNewsResources(), getTopics() 등 네트워크 API를 호출하는 메서드가 정의된 인터페이스 및 구현체.
- NetworkNewsResource.kt, NetworkTopic.kt: 서버의 JSON 응답 구조에 정확히 일치하는 DTO(Data Transfer Object) 클래스.
- Ktor/Retrofit 클라이언트 설정 코드.
- 의존성: core:common왜 레벨 1인가?
- 오직 '외부 세계(서버)와의 소통'에만 집중합니다. 가져온 데이터가 DB에 저장되는지, 화면에 바로 표시되는지에 대해서는 전혀 알지 못합니다
core:notifications
- 비유: "알림 메시지 제작소 (Notification Message Factory)"
- 역할: 안드로이드 시스템 트레이에 표시될 로컬 알림(Local Notification)을 생성하고 게시(post)하는 기술적인 책임을 전담합니다. 이 모듈은 "어떤 내용으로, 어떤 아이콘을 가진, 어떤 채널에 속한 알림을 만들 것인가"에 대한 '방법(How)'을 알고 있습니다.
- 주요 내용물:
- SyncNotificationNotifier.kt: 데이터 동기화와 관련된 알림을 생성하고 시스템에 표시하는 클래스.
- NotificationBuilder.kt (가상): NotificationCompat.Builder를 사용하여 알림 객체를 만드는 세부 로직을 캡슐화한 헬퍼 클래스.
- 알림 채널(Notification Channel)을 생성하고 관리하는 코드.
- 주요 의존성 (레벨 0):
- core:common: Context를 안전하게 사용하거나 Coroutine을 다루기 위한 유틸리티를 사용합니다.
- core:model: 알림에 표시할 내용이 특정 데이터 모델(예: NewsResource)과 관련이 있다면, 해당 모델의 구조를 알아야 합니다.
- 왜 레벨 1인가?
- 이 모듈은 오직 '알림'이라는 안드로이드 프레임워크의 특정 기술을 다루는 데에만 집중합니다.
"언제 알림을 보내야 하는가?" 또는 "알림을 보내도 되는가?"와 같은 정책적인 결정(Policy Decision)은 이 모듈의 책임이 아닙니다. - 이 모듈은 그저 상위 계층(예: sync 모듈)으로부터 "이 내용으로 알림을 보내줘!"라는 명령을 받아서 실행하는 '기술 전문가'일 뿐입니다.
- 따라서 다른 레벨 1 모듈(network, database 등)에 대한 지식 없이, 오직 레벨 0의 기초 재료만으로 자신의 임무를 수행할 수 있습니다.
- 이 모듈은 오직 '알림'이라는 안드로이드 프레임워크의 특정 기술을 다루는 데에만 집중합니다.