Jetpack Compose 풍미의 클린 아키텍처
16937 단어 androidprogrammingkotlin
프로젝트의 패키지 구조는 다음 형식을 취합니다.
바닥부터 시작하여
PRESENTATION 레이어는 모든 UI 관련 코드를 유지합니다. 이 경우 todos 목록의 보기 및 보기 모델이 됩니다.
DOMAIN 계층은 모든 비즈니스 로직을 유지하고 프로젝트 방문자에게 코드가 수행하는 방식이 아니라 수행하는 작업에 대한 좋은 아이디어를 제공합니다. 이 레이어에는 다음이 있습니다.
사용 사례: 사용 사례당 하나의 파일,
저장소: 저장소 인터페이스
모델: 비즈니스 로직 사용 사례 및 UI에서 참조할 Todo와 같은 비즈니스 모델
데이터 계층:
저장소: 저장소 구현
DataSource: 모든 데이터 소스 인터페이스 및 데이터 소스 엔터티. 이러한 엔터티는 도메인 모델과 다르며 API의 요청 및 응답 개체에 직접 매핑됩니다.
마지막으로 CORE 레이어는 상수, 구성 또는 의존성 주입(우리가 다루지 않을 것임)과 같은 모든 레이어에서 공통적인 모든 구성 요소를 유지합니다.
우리의 첫 번째 작업은 항상 도메인 모델 및 데이터 엔터티로 시작하는 것입니다.
data class Todo(
val id: Int,
val isCompleted: Boolean,
val task: String
)
data class TodoAPIEntity(
val id: Int,
val completed: Boolean,
val title: String
)
fun TodoAPIEntity.toTodo(): Todo {
return Todo(
id = id,
isCompleted = completed,
task = title
)
}
이제 TodoDatasource에 대한 인터페이스를 작성해 보겠습니다. 데이터 소스(api, db 등)의 작동 방식을 적용하려면 하나가 필요합니다.
import za.co.nanosoft.cleantodo.Domain.Model.Todo
interface TodoDataSource {
suspend fun getTodos(): List<Todo>
}
이 인터페이스의 구현을 작성하기에 충분하며 이를 TodoAPIImpl이라고 합니다.
interface TodoApi {
@GET("todos")
suspend fun getTodos(): List<TodoAPIEntity>
companion object {
var todoApi: TodoApi? = null
fun getInstance(): TodoApi {
if (todoApi == null) {
todoApi = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build().create(TodoApi::class.java)
}
return todoApi!!
}
}
}
class TodoAPIImpl : TodoDataSource {
override suspend fun getTodos(): List<Todo> {
return TodoAPI.getInstance().getTodos().map { it.toTodo() }
}
}
참고: 이 저장소의 getTodos 함수는 Todo 목록을 반환합니다. 따라서 TodoEntity -> Todo를 매핑해야 합니다.
TodoRepositoryImpl을 작성하기 전에 도메인 계층에 대한 인터페이스를 작성하겠습니다.
interface TodoRepository {
suspend fun getTodos(): List<Todo>
}
class TodoRepositoryImpl(private val datasource: TodoDataSource) : TodoRepository {
override suspend fun getTodos(): List<Todo> {
return datasource.getTodos()
}
}
이제 TodoRepositoryImpl이 데이터 소스를 교체하는 데 유용한 종속성으로 모든 데이터 소스를 사용할 수 있음을 알 수 있습니다.
이제 todo 저장소가 있으므로 GetTodos 사용 사례를 코딩할 수 있습니다.
class GetTodos(
private val repository: TodoRepository
) {
suspend operator fun invoke(): List<Todo> {
return repository.getTodos()
}
}
그런 다음 프레젠테이션의 뷰 모델과 뷰를 작성할 수 있습니다.
class TodoViewModel constructor(
private val getTodosUseCase: GetTodos
) : ViewModel() {
private val _todos = mutableStateListOf<Todo>()
val todos: List<Todo>
get() = _todos
suspend fun getTodos() {
viewModelScope.launch {
_todos.addAll(getTodosUseCase())
}
}
}
@Composable
fun TodoListView(vm: TodoViewModel) {
LaunchedEffect(Unit, block = {
vm.getTodos()
})
Scaffold(
topBar = {
TopAppBar(
title = {
Text("Todos")
}
)
},
content = {
Column(modifier = Modifier.padding(16.dp)) {
LazyColumn(modifier = Modifier.fillMaxHeight()) {
items(vm.todos) { todo ->
Row(modifier = Modifier.padding(16.dp)) {
Checkbox(checked = todo.isCompleted, onCheckedChange = null)
Spacer(Modifier.width(5.dp))
Text(todo.task)
}
Divider()
}
}
}
}
)
}
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
val vm = TodoViewModel(
getTodosUseCase = GetTodos(
repository = TodoRepositoryImpl(
api = TodoAPIImpl()
)
)
)
super.onCreate(savedInstanceState)
setContent {
CleantodoTheme {
TodoListView(vm)
}
}
}
}
요약하자면:
Reference
이 문제에 관하여(Jetpack Compose 풍미의 클린 아키텍처), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/paulallies/clean-architecture-in-the-flavour-of-jetpack-compose-1j1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)