帮助你为 Android 与 Kotlin 多平台项目设计和落地整洁架构方案。
复制安装指令,让 AI 自动完成配置 · 推荐新手
请帮我安装 askskill 上的 "android-clean-architecture" 技能: 1. 下载 https://raw.githubusercontent.com/affaan-m/ECC/main/docs/zh-CN/skills/android-clean-architecture/SKILL.md 2. 保存为 ~/.claude/skills/android-clean-architecture/SKILL.md 3. 装好后重载技能,告诉我可以用了
请为一个使用 Kotlin Multiplatform 和 Android 的应用设计 Clean Architecture 目录结构,包含 domain、data、presentation 模块职责、依赖方向,以及每层应放哪些类。
一份清晰的分层与模块设计建议,说明各层职责、依赖规则和推荐文件组织方式。
我在做一个待办事项应用,请基于 Clean Architecture 设计获取任务列表、创建任务、完成任务的 use case,以及 repository interface,并给出 Kotlin 示例代码。
包含用例类、仓库接口和示例代码的方案,便于直接映射到业务层实现。
请帮我把现有 Android 项目的数据层重构为 Clean Architecture 风格,说明 remote data source、local data source、repository implementation、DTO 到 domain model 映射应如何组织,并列出重构步骤。
一套数据层重构指南,包含结构建议、映射关系说明和可执行的迁移步骤。
适用于 Android 和 KMP 项目的整洁架构模式。涵盖模块边界、依赖反转、UseCase/Repository 模式,以及使用 Room、SQLDelight 和 Ktor 的数据层设计。
project/
├── app/ # Android 入口点,DI 装配,Application 类
├── core/ # 共享工具类,基类,错误类型
├── domain/ # 用例,领域模型,仓库接口(纯 Kotlin)
├── data/ # 仓库实现,数据源,数据库,网络
├── presentation/ # 界面,ViewModel,UI 模型,导航
├── design-system/ # 可复用的 Compose 组件,主题,排版
└── feature/ # 功能模块(可选,用于大型项目)
├── auth/
├── settings/
└── profile/
app → presentation, domain, data, core
presentation → domain, design-system, core
data → domain, core
domain → core (或无依赖)
core → (无依赖)
关键:domain 绝不能依赖 data、presentation 或任何框架。它仅包含纯 Kotlin 代码。
每个 UseCase 代表一个业务操作。使用 operator fun invoke 以获得简洁的调用点:
class GetItemsByCategoryUseCase(
private val repository: ItemRepository
) {
suspend operator fun invoke(category: String): Result<List<Item>> {
return repository.getItemsByCategory(category)
}
}
// Flow-based UseCase for reactive streams
class ObserveUserProgressUseCase(
private val repository: UserRepository
) {
operator fun invoke(userId: String): Flow<UserProgress> {
return repository.observeProgress(userId)
}
}
领域模型是普通的 Kotlin 数据类——没有框架注解:
data class Item(
val id: String,
val title: String,
val description: String,
val tags: List<String>,
val status: Status,
val category: String
)
enum class Status { DRAFT, ACTIVE, ARCHIVED }
在领域层定义,在数据层实现:
interface ItemRepository {
suspend fun getItemsByCategory(category: String): Result<List<Item>>
suspend fun saveItem(item: Item): Result<Unit>
fun observeItems(): Flow<List<Item>>
}
协调本地和远程数据源:
class ItemRepositoryImpl(
private val localDataSource: ItemLocalDataSource,
private val remoteDataSource: ItemRemoteDataSource
) : ItemRepository {
override suspend fun getItemsByCategory(category: String): Result<List<Item>> {
return runCatching {
val remote = remoteDataSource.fetchItems(category)
localDataSource.insertItems(remote.map { it.toEntity() })
localDataSource.getItemsByCategory(category).map { it.toDomain() }
}
}
override suspend fun saveItem(item: Item): Result<Unit> {
return runCatching {
localDataSource.insertItems(listOf(item.toEntity()))
}
}
override fun observeItems(): Flow<List<Item>> {
return localDataSource.observeAll().map { entities ->
entities.map { it.toDomain() }
}
}
}
将映射器作为扩展函数放在数据模型附近:
// In data layer
fun ItemEntity.toDomain() = Item(
id = id,
title = title,
description = description,
tags = tags.split("|"),
status = Status.valueOf(status),
category = category
)
fun ItemDto.toEntity() = ItemEntity(
id = id,
title = title,
description = description,
tags = tags.joinToString("|"),
status = status,
category = category
)
@Entity(tableName = "items")
data class ItemEntity(
@PrimaryKey val id: String,
val title: String,
val description: String,
val tags: String,
val status: String,
val category: String
)
@Dao
interface ItemDao {
@Query("SELECT * FROM items WHERE category = :category")
suspend fun getByCategory(category: String): List<ItemEntity>
@Upsert
suspend fun upsert(items: List<ItemEntity>)
@Query("SELECT * FROM items")
fun observeAll(): Flow<List<ItemEntity>>
}
-- Item.sq
CREATE TABLE ItemEntity (
id TEXT NOT NULL PRIMARY KEY,
title TEXT NOT NULL,
…
提供地道 Kotlin 设计模式与最佳实践,帮助构建健壮高效且易维护的应用