모든 개발자들의 숙명
지속가능한…코드..
class MainViewModel (application: Application) : AndroidViewModel(application) {
fun getString () : String? {
return getApplication<Application>().resources.getString(R.string.sample_string)
}
}
다음과 같은 방식에는 문제가 있다.
- 뷰모델은 주로 상태와 동작을 관리하지만 String등의 리소스는 view 계층에 속하기때문 → 관심사 분리가 제대로 안 됨
- 단위 테스트 어려움 → context를 사용하므로.. 뷰모델의 단위 테스트가 어려워짐
- 이전 데이터를 표시할 가능성 → 뷰모델은 한 번만 생성되기때문에, 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