__**Using String Resources in a ViewModel**__

2023. 8. 8. 11:33개발/Kotlin

모든 개발자들의 숙명

지속가능한…코드..

class  MainViewModel (application: Application) : AndroidViewModel(application) { 
    fun  getString () : String? { 
        return getApplication<Application>().resources.getString(R.string.sample_string) 
    } 
}

다음과 같은 방식에는 문제가 있다.

  1. 뷰모델은 주로 상태와 동작을 관리하지만 String등의 리소스는 view 계층에 속하기때문 → 관심사 분리가 제대로 안 됨
  1. 단위 테스트 어려움 → context를 사용하므로.. 뷰모델의 단위 테스트가 어려워짐
  1. 이전 데이터를 표시할 가능성 → 뷰모델은 한 번만 생성되기때문에, string 값 등이 변경되면 이전 데이터를 표시할 수 있음

그럼 어쩐다????????

UI계층에서 sealed class 사용

아래와 같이 해줍니다

sealed class StringValue {

    data class DynamicString(val value: String) : StringValue()

    object Empty : StringValue()

    class StringResource(
        @StringRes val resId: Int,
        vararg val args: Any
    ) : StringValue()

    fun asString(context: Context?): String {
        return when (this) {
            is Empty -> ""
            is DynamicString -> value
            is StringResource -> context?.getString(resId, *args).orEmpty()
        }
    }
}

in ViewModel

아래와 같이 사용합니다

private val _logMessage by lazy { MutableLiveData<StringValue>() }
val logMessage: LiveData<StringValue>
    get() = _logMessage

_logMessage.postValue(StringResource(R.string.invalid_type))

logMessage.observe(this@MainActivity) { 
            debug(TAG, it.asString(this@MainActivity))
        }

Uploaded by N2T

'개발 > Kotlin' 카테고리의 다른 글

to clean code (in Kotlin)  (0) 2023.10.23
Viewmodel / manage string res  (0) 2023.10.23
Retrofit to Ktor  (0) 2023.07.26
Kotlin Unpacking params  (0) 2023.07.26
Kotlin <in, out, where>  (0) 2023.07.26