일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 코틀린 문자열
- 내용의동일성
- kotlin listview
- isNullOrBlank
- 코틀린 lateinit
- 프로그래머스
- 코틀린 컬렉션함수
- add view
- 코틀린
- class
- 코틀린 람다함수
- 코틀린 제너릭
- 코틀린 중첩클래스
- 컬렉션함수
- 해시
- kotlin collection
- kotlin addview
- Kotlin Generic
- 코틀린 내부 클래스
- 카카오 순위검색
- 코틀린 data class
- Kotlin
- 객체의 동일성
- collection function
- kotlin recyclerview
- kakao blind
- 컬렉션 함수
- programmers # 프로그래머스 #큰수비교 #cmp_to_key()
- 프로그래머스 #탐욕법 #큰수만들기 #join #python
- lateinit
- Today
- Total
엔지니어 규의 IT 프로그래밍 다이어리
[Kotlin] 16. 익명객체와 옵저버 패턴 (난이도 : ★★★★★) 본문
옵저버
'옵저버' 란 '이벤트가 일어나는 것을 감시' 하는 감시자의 역할을 만든다고 하여 Observer 라고 부른다.
안드로이드를 예로 들자면 '키의 입력', '터치의 발생', '데이터의 수신' 등 함수로 직접 요청은 안했어도 시스템 또는 루틴에의 해 발생하는
동작들을 '이벤트' 라고 부르며 이 이벤트가 발생할때마다 즉각 처리하도록 만드는 패턴을 '옵저버 패턴'이라고 한다.
옵저버 패턴을 구현할 때는 두개의 클래스가 필요하다.
위 그림처럼 class A는 이벤트를 수신하고 class B는 이벤트의 발생 및 전달을 처리한다고 할때, 이와 같은 방법에는 문제가 있다.
일반적으로 이벤트를 수신하는 class A 의 필요에 따라 이벤트를 발생시키는 클래스의 인스턴스를 생성하여 사용하기 때문에,
A 는 B를 직접 참조 할 수 있지만, B는 A 를 참조할 방법이 없다.
그래서 이사이에 '인터페이스'를 끼워 넣는다.
B에서는 자신의 이벤트를 받아줄 수 있는 인터페이스를 만들어 공개하고, A는 이를 구현하여 B에 넘겨주면
인터페이스만 알아도 event를 넘겨줄 수 있다. 이때 이 인터페이스를 'observer' 또는 'listener' 라고 부르며
이렇게 이벤트를 넘겨주는 행위를 'call back' 이라고 한다.
이해를 돕기위해 코드를 통해서 더 자세히 알아보도록 하자
우리가 구현할 코드는
이벤트를 수신해서 출력하는 EventPrinter,
숫자를 카운트하며 5의 배수마다 이벤트를 발생시킬 Counter,
이 두개를 연결시킬 인터페이스인 EventListener 로 이루어져 있다.
아래 코드를 확인해 보자.
fun main(){
EventPrinter().start()
}
interface EventListener{
fun onEvent(count: Int)
}
class Counter(var listener: EventListener){
fun count(){
for (i in 1..100){
if(i % 5==0) listener.onEvent(i)
}
}
}
class EventPrinter : EventListener {
override fun onEvent(Count :Int){
print("${Count}-")
}
fun start(){
val counter = Counter(this)
counter.count()
}
}
5-10-15-20-25-30-35-40-45-50-55-60-65-70-75-80-85-90-95-100-
여기서 Counter의 인스턴스를 만들되, this 라는 키워드로 EventListener의 구현부를 넘겨준다.
그리고 counter.count() 구문을 적어줌으로써 count를 시작한다.
fun start(){
val counter = Counter(this)
counter.count()
}
여기서 this 는 EventPrinter 객체 자신을 나타내지만 받는쪽에서 'EventListener'만 요구했기떄문에,
EventListener 구현부만 넘겨주게 된다.
이를 객체지향의 다형성이라고 한다.
상속받아 만들어진 class 는 super class의 기능을 포함하여 제작되었으므로, super class 에서 정의한 부분만 따로 넘겨줄 수 있다.
EventPrinter.start() 를 main 함수에서 실행해보면 Counter 가 5의 배수마다 이벤트를 발생시킨것을,
EventPrinter 내에서 구현된 EventListener에서 출력하고 있음을 알 수 있다.
익명 객체 (Anonymous Object)
그런데 EventPrinter가 EventListener를 상속받아 구현하지 않고, 임시로 만든 EventListener 객체를 대신 넘겨줄 수 도 있다.
이것을 이름이 없는 객체라고 하여 익명객체(Anonymous Object)라고 부른다.
fun main(){
EventPrinter().start()
}
interface EventListener{
fun onEvent(count: Int)
}
class Counter(var listener: EventListener){
fun count(){
for (i in 1..100){
if(i % 5==0) listener.onEvent(i)
}
}
}
class EventPrinter {
fun start(){
val counter = Counter(object: EventListener{
override fun onEvent(count: Int){
print("${count}-")
}
})
counter.count()
}
}
위의 코드를 실행해보면 같은결과가 나오는것을 알 수 있다.
observer 패턴은 이벤트를 기반으로 동작하는 모든 코드에서 광범위하게 쓰이는 방식이므로 그 구조를 이해하는것이 중요하다.
---------------------------------------------------------------------------------------------
번외 +
개인적으로 디자인 패턴은 코딩을 하면서 굉장히 중요한것으로 보이며, 또한 어려운 개념이기도 하다.
위의 개념은 차근차근 오랜시간동안 보며 이해를 해야 할 것 같다.
'프로그래밍 언어 > 코틀린' 카테고리의 다른 글
[Kotlin] 18. 제너릭 (0) | 2022.05.24 |
---|---|
[Kotlin] 17. 클래스의 다형성 (0) | 2022.05.23 |
[Kotlin] 15. 오브젝트 (0) | 2022.05.19 |
[Kotlin] 14. 스코프 함수(scope function) (0) | 2022.05.19 |
[Kotlin]13. 고차 함수와 람다 함수 (0) | 2022.05.18 |