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

흐름을 어떻게 해야할지 모르겠습니다 조언좀 해주세요.

0 추천

앱의 흐름부터 설명드리겠습니다.

바텀 내비게이션을 사용중입니다

A, B, C 프래그먼트가 존재합니다.

A -> B -> C 프래그먼트 순으로 이동하는 순서이고

B에서 어떤 데이터를 선택하고, 이 데이터를 C로 보냅니다.

C 에서는 이 데이터에 대한 상세 페이지를 작성하는 페이지입니다.

C에서 작성을 다 하면, 저장 버튼을 눌러 페이지가 종료됨가 동시에 A로 이동합니다.

현재는 C에서 저장 버튼을 누를떄 DB에 저장하고 있습니다.

 

이제 A로 돌아와 A에서는 C에서 DB에 저장했던 데이터를 불러와 뷰에 뿌려줍니다.

여기까지는 잘 동작하기는 했습니다..

 

생각해보니 A프래그먼트에서도 이 종합적으로 받은 데이터를 최종적으로 DB에 저장해야한다는 것입니다.

그래서 저는 C에서도 저장하고 A에서도 저장하는것은 이상하니.. (C에서 이미 DB에 저장했으니까요..)

C에서는 그냥 A로 데이터를 보내기만하고 A에서 최종저장을 하려고 계획을 변경하려고 합니다.

 

이제 질문을 드리면 C에서 사용하던 Entity 클래스를 A로 보내려고하는데..

지난번에 질문드렸을때처럼 safeArgs랑 Parcelable을 이용하려고합니다.

그런데 A는 프래그먼트 즉 Presentation레이어이고 Entity 클래스는 Data 레이어이고

계층구조가 

Presentation -> Domain -> Data 이렇게 되어있는데

Entity 클래스가 속한 Data 레이어에서 Fragment인 Presntation으로 데이터 전달은 이상한것 같습니다

지난번에 Parcelable을 사용해도 되는데 이러한 계층간 이동은 하지말라고 하신게 이뜻인것 같은데요..

 

질문이

1. 제가 궁금한게..C 프래그먼트에서 Entity클래스를 A프래그먼트로 보내는거니까 Presentation 간의 이동이라고 이해하면 안될까요?

2. 1번은 저러한 것으로 이해하면 안되는지 질문드린거였고, 지금 상황처럼 Entity 클래스처럼 Data레이어에서 Presentation으로 데이터를 알맞게 전달하려면 어떻게 해야하나요?

3. 현재는 C에서 DB에 저장하고 있다고 말씀드렸는데, 이 말은 C에서 Entity를 사용하고 있다는 말이잖아요?이제 A로 데이터를 보내기만하는 것으로 계획을 변경하면 Entity 클래스는 C에서 저장하지 않기에 필요가 없어지는데 일반 클래스로 만들어 A에로 보내고 A에서 저장할때 이 Entity 클래스로 맵핑하여 사용하는 방식으로 해야하나요 아니면 그냥 그대로 계속 Entity 클래스를 사용해도 되나요?

 

 

 

 

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

1개의 답변

0 추천

Navigation compoment를  사용 중이시죠?
구조를 복잡하게 가져가지 마시고 A, B, C를 nested graph에 넣고 viewmodel를  nested graph 내에서 공유하는 방법을 사용해 보세요. 자세한 아래 링크를 참조하세요.

https://developer.android.com/guide/navigation/navigation-nested-graphs

https://developer.android.com/guide/navigation/navigation-programmatic#share_ui-related_data_between_destinations_with_viewmodel

추가로 질문하신 항목에 대해서 말씀 드리자면

1. 핵심포인트는 UI에 사용되는 데이이구조와 DB에 사용되는 구조가 다르거나 달라질 가능성이 있다면 분리해서 사용하라는 것입니다. 이건 소프트웨어 엔지니어링에서 지속적으로 강조하는 내용입니댜.

2. UI에 필요한 데이터를 가질 수 있도록 만드시면 됩니다. 화면 디자인을 보시면 어떤 값들이 필요하신지 이해가 가실겁니다. 다만 ID와 같이 아이템간의 구분을 지을 수 있는 키값은 UI쪽에서도 가지고 있어야 겠죠. 이 둘간의 매핑은 간단하게 확장함수나 멤버함수를 사용해서 서로간의 구조에 맞게 변환하시면 됩니다. PersonDBEntity와 PersonUiModel을 변환한 다면, 아래와 같이 하시면 됩니다. 맴핑시 별도의 클래스를 쓰느냐, 멤버함수를 사용하느냐는 개인의 선택사항입니다.

@Entity
data class PersonDBEntity(
    @PrimaryKey
    val id: Long,
    val firstName: String,
    val lastName: String,
    val gender: Int = 0
)

data class PersonUiModel(
     val id: Long,
     val name: String,
     val gender: String
)


fun PersonDBEntity.toUiModel(): PersonUiModel {
     return PersonUiModel(
         id = this.id,
         name = "$firstName $lastName",
         gender = when (this.gender) {
               1 -> "Male"
               2 -> "Female"
              else -> ""
        }
     )
}

 

3. 이것도 결국 1번과 같은 질문이 됩니다. 레이어가 분리되어 있다면, 특히 UI와 다른 레이어간에는 데이터모델을 분리해서 사용하시는게 프로젝트 사이즈가 커질수록 유리합니다. 이게 일반적인 권장사항입니다. 화면간 넘기는 데이터는 UI용 데이이터라고 보는게 맞을 것 같습니다. 물론 프로젝트 사이즈가 작다면 이런 구분이 무의미해질 수도 있습니다만, 대부분의 업무용앱은 아키텍쳐가 핖요한 사이즈의 앱입니다. 따라서 레이어의 분리, 데이터 모델의 분리등은 자연스럽게 필요하게 됩니다..

spark (224,800 포인트) 님이 2022년 8월 13일 답변
spark님이 2022년 8월 15일 수정
그렇다면 3번답변에서 Entity 클래스가 존재하고 이것은 DB를 위한 클래스이므로 UI용 클래스, 설령 프로퍼티가 모두 일치한다하더라도 별도로 만들어 주는게 더 좋을수 있다 라는 말씀이시죠?, 선생님이 답변해주신 2번 코드에서는 프로퍼티가 약간은 다르지만 만약 같다고 했을시에 저렇게 따로 만들어주는게 어떻게 보면 더좋다라는 것이죠?
네. 대부분의 경우 화면에서 요구되는 데이터의 구조는 DB와는 다르게 될 확률이 매우 높기 때문에, 데이터모델을 공유할 경우, UI에 대한 변경이 생겨거나, DB에 대한 변경이 생길경우 불필요하게 상대 레이어를 건드릴게 되기 때문에 분리를 하는 것이 좋습니다. 이건 말씀드렸듯이 소프트웨어 엔지니어링에서 오랫동안 사용되어 온 일반적인 룰이예요.
...