마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

꼭 데이터를 repository에서 생성할 필요가 있나요?

0 추천
class DetailRepository(private val workoutDao : WorkoutDao, title: String) {
    private val workout = Workout(title = title)
    private var setInfoList = ArrayList<WorkoutSetInfo>()
    private lateinit var updatedList : List<WorkoutSetInfo>

    fun changeUnit(unit: WorkoutUnit) {
       updatedList = setInfoList.map { setInfo ->
            setInfo.copy(unit = unit)
        }
    }

    fun add() {
        setInfoList.let { list ->
            val item = WorkoutSetInfo(set = setInfoList.size + 1)
            list.add(item)
            updatedList = setInfoList.toList()
        }
    }

    fun delete() {
        if(setInfoList.size != 0) {
            setInfoList.let { list ->
                list.removeLast()
                updatedList = list.toList()
            }
        }
        return
    }

    fun save() {
        val workoutId = workoutDao.insertWorkout(workout) // Workout 삽입 및 삽입된 Workout의 ID 반환
        val newWorkoutSetInfoList = setInfoList.map { setInfo -> // workoutId를 기반으로 새 리스트 리턴
            setInfo.copy(parentWorkoutId = workoutId)
        }
        workoutDao.insertSetInfoList(newWorkoutSetInfoList)
        setInfoList.clear()
    }

    fun clear() {
        setInfoList.clear()
        updatedList = setInfoList.toList()
    }

    // toList를 하는 이유는 새로운 리스트를 반환하기때문에 postValue 가능하게끔 하기 위함
    fun getList() : List<WorkoutSetInfo> = updatedList
}

 

ViewModel

class DetailViewModel(val repository: DetailRepository, title: String) : ViewModel() {
    private var _items: MutableLiveData<List<WorkoutSetInfo>> = MutableLiveData()
    var testNum : Int = 0
    val items: LiveData<List<WorkoutSetInfo>>
        get() = _items

    fun changeUnit(unit: WorkoutUnit) {
        repository.changeUnit(unit)
        _items.postValue(repository.getList())
    }

    fun addSet() {
        viewModelScope.launch(Dispatchers.IO){
            repository.add()
            _items.postValue(repository.getList()) // plus를 사용하면 새로운 List가 반환
        }
    }

    fun deleteSet() {
        repository.delete()
        _items.postValue(repository.getList())
    }

    fun save() {
        viewModelScope.launch(Dispatchers.IO) {
            repository.save()
        }
    }

    fun clear() {
        viewModelScope.launch(Dispatchers.IO){
            repository.clear()
            _items.postValue(repository.getList())
        }
    }
}

위 코드처럼 repository에서 workout이라는 데이터와 setinfolist를 생성하고

뷰모델에서 사용해서 화면을 업데이트합니다.

이전 질문의 답변에서 화면단위 임시 입력은ViewModel 에서, db같은 곳에 영구저장하는 건 repository에서 하시는게 적합해보이신다고 하셨는데

그럼 지금 현재 Repository에 있는 Workout, setInfoList같은 데이터를 생성하는 코드를 Repository가 아니라

Viewmodel에서 진행하고 DB에 저장할때는 Repo로 옮겨서 하라 이말씀인가요?.

이렇게 ㄷ데이터의 생성같은것을 Repo가 아니라 ViewModel에서 직접하고 해해도 괜찮으을까요?

뭐 mvvm의 관점이나 이런것에서요.

 

 

--

 

아 그리고 nested_graph를 사용해서 by activityviewmodel이나 by navGraphViewmodel()을 사용하라고 하시는 것도 추천하시던데..이전에 그걸 사용하는데 그.. 데이터가 자꾸 공유가 돼서 그냥 일반 

by viewmodels()를 사용하는 다른 방법으로 바꿨습니다 ㅠ

codeslave (3,940 포인트) 님이 2022년 11월 19일 질문

1개의 답변

0 추천

이렇게 데이터의 생성같은것을 Repo가 아니라 ViewModel에서 직접하고 해해도 괜찮으을까요?

위 질문에 대한 쩨 의견을 말씀드리면,

결국은 본인의 선택사항입니다.  100% 정답이란게 없으므로, 이렇게 해서 이득이 더 많다면 하시면 됩니다. 특히 나중에 다시 같은 코드를 가지고 변경을 할 때 빠르게 어렵지 않게 처리할 수 있을지를 고민해 보세요.

그리고 화면을 기존 데이터가 누적되는 문제는 A, B, C화면에서 A화면의 onViewCteate같은 곳에서 기존에 입력했던 데이터를 초기화 하시면 해결되지 않을까요?

제가 정확하게 이해를 했는지는 모르겠지만, 아래와 같이 두가지 다른 리스트을 관리할 필요가 있어 보입니다.

ListAll => 현재 까지 입력한 모든 데이터를 보관

ListTemp => A, B, C화면을 통해 입력받는 데이터 저장. C화면에서 A화면으로 돌아가면 ListAll에 데이터를 추가하고  초기화.
 

spark (226,420 포인트) 님이 2022년 11월 19일 답변
spark님이 2022년 11월 19일 수정
선생님 리스트 두개 사용하는건 nested_graph를 사용할때를 가정하고 말씀하신거죠?
nested_graph를 꼭 사용할 때라고 단정지을 수는 없겠죠? repository와 ViewModel, navigation graph이 세가지 모두가 맞물려 돌아가는 거라 여러가지 조합이 생길 수 있을 것 같네요. 각 레이어가 담당할 역할을 정하시고 거기에 맞춰서 구조를 가져가세요.
글쎄요, 그럴 수도 있고 아닐 수도 있겠죠. Navigation graph, ViewModel, Repository 구조를 어떻게 가져가느냐에 따라 달라질 수 있을 겁니다. 다시 말씀드리지만 정답이 없어요.
...