Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EventObserver를 사용해 코드를 단순화해보자 #17

Open
taeheeL opened this issue Mar 19, 2023 · 0 comments
Open

EventObserver를 사용해 코드를 단순화해보자 #17

taeheeL opened this issue Mar 19, 2023 · 0 comments
Assignees
Labels

Comments

@taeheeL
Copy link

taeheeL commented Mar 19, 2023

기존 LiveData의 문제점?

LiveData는 UI에 표시되는 데이터와 같이, 자주 업데이트해야 하는 데이터를 보유하는 데 사용되는 ObseravleData holder class 입니다. LiveData를 통해 저희는 데이터의 변경 사항을 Observing 하고 그에 따라 UI를 업데이트 하거나 다양한 로직 처리를 해왔습니다.

그러자 LiveData에는 제한이 있습니다. LiveData의 value를 내보내면 새 관찰자가 등록될 때마다 동일한 값을 계속 내보냅니다. 즉, LiveData가 이미 값을 내보낸 이후에 관찰자가 등록되면 이전 관찰자가 value를 이미 소비했더라도 관찰자는 등록 즉시 해당 value를 받습니다.

이로 인해 동일한 데이터가 여러 번 처리되는 경우, 의도하지 않은 동작이 발생할 수 있습니다. 동일한 작업을 여러 번 트리거 하지 않도록 저희는 수동적으로 처리 여부를 확인하는 코드를 작성하고는 했었습니다.

그렇다면 어떻게 해결하는 것이 좋은가?

이 문제를 해결하기 위해서 현업에서는 EventObserver를 사용합니다. Event는 단순히 관찰해야 하는 데이터를 감싸는 Wrapper이며, EventObserver는 이 Event를 한 번만 소비하는 역할을 합니다. Event가 Observe 된 후에 Event를 "소비됨"으로 식별하여 나중에 다시 트리거하지 않도록 합니다.

이렇게 하면 이벤트가 한 번만 처리되어 동일한 데이터가 여러 번 처리될 때 발생할 수 있는 의도하지 않은 동작을 방지할 수 있습니다. 또한 이벤트가 이미 처리되었는지 여부를 수동으로 추적할 필요가 없어 코드를 단순화합니다.

아래의 코드를 붙여드립니다. 앞으로 작업하실 때 사용하시면 좋을 것 같아 공유드립니다~

class Event<T>(private val content: T) {

    private var hasBeenHandled = false

    fun getContentIfNotHandled(): T? {
        return if (hasBeenHandled) {
            null
        } else {
            hasBeenHandled = true
            content
        }
    }
}

class EventObserver<T>(private val onEventUnHandledContent: (T) -> Unit) : Observer<Event<T>> {
    override fun onChanged(event: Event<T>?) {
        event?.getContentIfNotHandled()?.let {
            onEventUnHandledContent(it)
        }
    }
}

아래는 공식적인 샘플입니다. 참고하세요!

https://github.com/android/architecture-samples/blob/dev-dagger/app/src/main/java/com/example/android/architecture/blueprints/todoapp/Event.kt

@taeheeL taeheeL self-assigned this Mar 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant