티스토리 뷰

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

원문 : https://qiita.com/takahirom/items/6907e810d3661e19cfcf

 

Compose는 인수에 같은 오브젝트를 전달했을때 Composable함수를 깔끔하게 처리해줍니다.하지만 그러기 위해서는 몇가지 조건이 있습니다.

앱 모듈과 모델 뮤듈이 있어서, 앱 모듈에는 컴포즈가 적용되어 있고 Composable 함수도 있지만, 모델 모듈에는 간단하게 Article 클래스만 있다고 해봅시다.

그중 같은 오브젝트를 전달했을경우 스킵해주는 것은 Composable2 뿐입니다 

아래 코드를 봐주세요.

app module ------------> model module
fun Composable1()        class Articles
fun Composable2()        class Article
fun Composable3()                                         

app module

@Composable
fun Composable1(articles: Articles) {
  Text(text = "Hello $articles!")
}

@Stable
data class UiModel(val articles: Articles)

@Composable
fun Composable2(uiModel: UiModel) {
  Text(text = "Hello $uiModel!")
  uiModel.articles.articles.forEach {
    Composable3(it)
  }
}

@Composable
fun Composable3(article: Article) {
  Text(text = "Hello $article!")
}

model module

data class Articles(val articles: List<Article>)
data class Article(val title: String)

이것은 Compose Compiler Metrics를 사용하면 확인할수 있습니다. restartable로 되어 있어서、skippable로 되어있는 경우에는 인수가 인수가 같아도 Skip되지 않습니다.
app_release-composables.txt

restartable fun Composable1(
  unstable articles: Articles
)
restartable skippable fun Composable2(
  stable uiModel: UiModel
)
restartable fun Composable3(
  unstable article: Article
)

 

그럼 어떻게 대처하면 될까?

3가지 방법을 생각해볼 수 있습니다.

해결책 1: @Stable인 클래스를 래핑하는 방법 

첫번째는 Composable2의 함수처럼 UiModel클래스를 래핑하는 것입니다.   그렇게함으로써 Compose에 이 오브젝트를 변경할수 없다는 것을 전달 할 수 있습니다.  이 경우 항상 Stable 클래스를 래핑하는것을 의식하며 개발할 필요가 있습니다.

@Stable
data class UiModel(val articles: Articles)

@Composable
fun Composable2(uiModel: UiModel) {
  Text(text = "Hello $uiModel!")
  uiModel.articles.articles.forEach {
    Composable3(it)
  }
}

해결책 2 : 모델이 있는 모듈에도 Compose의 컴파일러를 동작시키는 방법

Articles클래스가 있는 Model 모듈도 Compose 컴파일러를 동작시키는 방법도 생각해볼 수 있습니다.  이렇게 함으로써 Compose가 Article등의 클래스를 인식할 수 있기 때문에 잘 동작됩니다.

하지만 이 방법을 사용할 경우 Compose의 런타임 디펜던시를 필요로 하기때문에 Jetpack Compose를 UI프레임워크로 사용하는 경우에는 UI와 분리하려고 할때 깔끔하지 못하다고 느낄 수 있습니다. ( Composable의 구조를 내용 변경이 가능한가 아닌가를 관리하는 툴로서 사용한다면 적용하는 것이 좋을수도 있겠습니다. )

다만, 이 경우에도 fun Composable1(articles: Articles)에서는 Recompose를 막을수는 없습니다.  왜냐하면 List는 MutableLIst의 인스턴스가 될 수 있기때문에 Stable이 아니기 때문입니다. 하지만 이건 다른 해결책을 사용하더라도 같은 문제를 포함하고 있습니다

unstable class Articles {
  unstable val articles: List<Article>
  <runtime stability> = Unstable
}

 

해결책 3 : UI 모델을 바꾸는 방법

물론 이 방법을 사용해서 UI 안의 클래스를 사용하면 해결할 수 있습니다.  이렇게 함으로써 분리 하는 것이 가능해집니다.

그러나 메리트만 있는 것은 아니고, 개발할때마다 매번 매핑코드를 구현하고 테스트하고, 리뷰, 관리 해 나가야하기때문에 그만큼 비용을 지불하는 셈입니다.ただ、

(이 방법은 Guide to app architecture에서 다루고 있습니다. https://developer.android.com/jetpack/guide/data-layer?hl=en#business-models )

끝맺음

각각의 방법은 장점 단점이 분명하기때문에 이 안에서 자신에게 잘 맞는 방법을 선택하는 것이 좋다고 생각합니다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
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
글 보관함