[Kotlin] Observer Pattern : 옵저버 패턴 알아보기

2022. 7. 5. 21:00· Kotlin/Design Patterns
목차
  1. 리액티브 프로그래밍과 옵저버 패턴
  2. 옵저버 패턴 사용
  3. RxJava의 옵저버 패턴
  4. Coroutine의 옵저버 패턴
  5. Kotlin의 Delegates.observable
  6. 옵저버 패턴 정리
반응형

리액티브 프로그래밍과 옵저버 패턴

리액티브 프로그래밍 패러다임은 최근 프로그래밍 패러다임 중 가장 중요한 패러다임 중 하나이다. 리액티브 프로그래밍 패러다임이 유행하기 이전에는 명령형 프로그래밍 패러다임이 유행했다. 명령형 프로그래밍 패러다임 하에서는 데이터가 변할 때 데이터가 변화에 따라 데이터가 변해야 하는 부분에 모두 적용을 시켜줘야 했다. 

 

리액티브 프로그래밍 패러다임은 데이터가 변하는 것을 관찰해서 데이터가 변할 때 동작을 변하도록 만드는 것을 기본으로 한다. 즉, 데이터에 반응(Reactive)하도록 코드를 만드는 것이다. 이렇게 하면 데이터가 변화할 때 변화가 필요한 부분에 변화를 관찰하도록 코드를 넣어주면 데이터가 변화했을 때 데이터 변화에 대한 변경 사항이 즉시 게시된다.

 

옵저버 패턴은 리액티브 프로그래밍의 기초가 되는 패턴이다. Observer(관찰자)는 데이터의 변화를 관찰하며, 관찰한 변화를  필요한 곳에  알린다. 따라서 옵저버 패턴은 기본적으로 발행자와 구독자 둘로 구성된다. 발행자는 변화하는 데이터이며, 구독자는 데이터의 변화를 관찰해 필요한 동작을 수행한다. 

 

 

 

옵저버 패턴 사용

데이터가 변화할 때 어떻게 옵저버 패턴이 동작하는 것일까? 옵저버 패턴은 데이터가 변화하면 이전 값과 변화한 값을 인자로 받는 메서드를 호출하는 방식으로 동작한다. RxJava의 Observable, Coroutines의 Flow, Kotlin에 기본으로 내장된 ObservableProperty, 등 가장 많이 사용되는 데이터들은 모두 같은 방식으로 구현된다. 직관적인 이해를 위해서 아래에서 각 옵저버 패턴이 어떻게 사용되는지 살펴보자.

 

RxJava의 옵저버 패턴

RxJava에서는 Observable을 통해 발행자를 생성하고 subscribe를 통해 구독자를 붙인다.

//발행자(Publisher)
val publisher : Observable<String> = Observable.create { emitter: ObservableEmitter<String> ->
    emitter.onNext("hello")
    emitter.onNext("kotlin")
    emitter.onComplete()
}

//구독자(Subscriber)
publisher.subscribe {
    println(it)
}

//출력
hello
kotlin

위의 코드에서는 publisher이 hello와 kotlin을 발행하고 subscriber은 해당 값을 구독해서 프린트를 하고 있다. 따라서 hello, kotlin이 순서대로 출력된다.

 

Coroutine의 옵저버 패턴

Coroutines에서는 flow를 통해 발행자를 생성하고 collect를 통해 구독자를 붙인다. 

//발행자(Publisher)
val flow = flow {
   emit("abc")
   emit("def") 
}

CoroutineScope(Dispatchers.IO).launch {
    //구독자(Subscriber)
    flow.collect {
        println(it)
    }
}

//출력
abc
def

위의 코드에서는 flow가 "abc", "def"를 발행하고 collect를 통해 붙여진 구독자는 해당 값을 출력한다.

 

Kotlin의 Delegates.observable

Kotlin의 Delegates.observable은 시작값(initialValue)과, 변경 시 동작(onChange)을 인자로 받는다. 값(data) 자체가 발행자이며, 변경 시 동작(onChange)을 구독자로 생각하면 된다.

var data: String by Delegates.observable(
    initialValue = "",
    //onChange : 구독자
    onChange = { property: KProperty<*>, oldValue: String, newValue: String ->
        println("Data Changed >> from ${oldValue} to ${newValue}")
    }
)

위의 코드에서는 data가 발행자이며, onChange의 람다식이 구독자이다. RxJava나 Coroutine의 예시들과는 다르게 발행자와 구독자가 한 번에 붙여진다. 또한 RxJava나 Coroutine은 하나의 발행자에 여러 구독자를 나눠서 붙일 수 있지만 Delegates.observable은 하나의 구독자만을 붙일 수 있다.

 

만약 위의 코드에 시작값을 ""으로 설정하고, "a", "b", "c"를 순서대로 발행하면 다음과 같이 순서로 값들이 출력된다.

Data Changed >> from  to a
Data Changed >> from a to b
Data Changed >> from b to c

 

전체 코드는 다음과 같다.

fun main() {
    var data: String by Delegates.observable(
        initialValue = "",
        //onChange : 구독자
        onChange = { property: KProperty<*>, oldValue: String, newValue: String ->
            println("Data Changed >> from ${oldValue} to ${newValue}")
        }
    )

    data = "a"
    data = "b"
    data = "c"
}

//출력
Data Changed >> from  to a
Data Changed >> from a to b
Data Changed >> from b to c

 

 

옵저버 패턴 정리

위의 사용 예시를 통해 옵저버 패턴이 어떤 것인지 직관적으로 이해할 수 있었을 것이다. 다양한 방식을 보여준 이유는 옵저버 패턴은 용도에 따라서 다양하게 구현될 수 있다는 것을 보여주기 위함이다. 

 

옵저버 패턴을 정리하면 다음의 말로 정리할 수 있다.

옵저버 패턴은 데이터의 변화를 관찰하기 위한 패턴이다.

 

반응형
저작자표시 비영리 변경금지
  1. 리액티브 프로그래밍과 옵저버 패턴
  2. 옵저버 패턴 사용
  3. RxJava의 옵저버 패턴
  4. Coroutine의 옵저버 패턴
  5. Kotlin의 Delegates.observable
  6. 옵저버 패턴 정리


 

Kotlin, Android, Spring 사용자 오픈 카톡

오셔서 궁금한 점을 질문해보세요!
비밀번호 : kotlin22

open.kakao.com

'Kotlin/Design Patterns' 카테고리의 다른 글
  • [Kotlin] 옵저버 패턴 직접 구현해보기
  • [Kotlin] 옵저버 패턴 내부 구현 살펴보기 : Delegates.observable은 어떻게 동작하는가?
  • [Delegate Pattern] 2. by 키워드를 이용하여 Delegate Pattern 구현하기
  • [Delegate Pattern] 1. Delegate Pattern이란?
Dev.Cho
Dev.Cho
'조세영의 Kotlin World'는 Kotlin를 전문적으로 다루는 개인 기술 블로그입니다. Kotlin 세계에 대한 양질의 자료를 제공하며 Kotlin, Android, Spring, CI, CD 분야에 대해 다룹니다.
Dev.Cho
조세영의 Kotlin World
Dev.Cho
전체
오늘
어제

블로그 메뉴

  • LinkedIn
  • GitHub
  • 분류 전체보기 (491)
    • Kotlin (104)
      • Class and Interface (19)
      • Variable and Function (8)
      • Modifier (5)
      • Collection (14)
      • Time (8)
      • 동시성 제어 (7)
      • Reactive Programming (2)
      • Paradigm (2)
      • Kotlin 자료구조 (15)
      • Design Patterns (11)
      • Algorithm (3)
      • Exception (1)
      • 기타 (9)
      • Update History (0)
    • Coroutines (32)
      • Coroutine Basics (18)
      • Flow (9)
      • CoroutineScope (3)
      • Debugging (2)
    • Testing Codes (28)
      • Test 기본 (3)
      • JUnit5 (9)
      • MockK (6)
      • Testing Coroutines (1)
      • Testing Android (8)
      • Test 기타 (1)
    • Spring (50)
      • Dependency Injection (18)
      • Settings (5)
      • REST API (0)
      • DevTools (1)
      • MVC (18)
      • Error (2)
      • MongoDB (2)
      • Database (4)
    • Android (39)
      • Architecture (2)
      • Component (5)
      • Manifest (1)
      • Lifecycle (2)
      • Dependency Injection (17)
      • Resource (1)
      • Storage (1)
      • Security and Optimization (1)
      • WebView (2)
      • Error (6)
    • Android Jetpack Compose (33)
      • Compose (6)
      • Compose Modifier (13)
      • Compose Resource (4)
      • Compose State (4)
      • Compose Side Effect (6)
    • Android Jetpack Compose UI (48)
      • Compose Layout (14)
      • Compose Text (10)
      • Compose Button (5)
      • Compose Dialog (2)
      • Compose TextField (0)
      • Compose UIs (4)
      • Compose Animation (1)
      • Compose Canvas (12)
    • Android Jetpack (10)
      • Datastore (5)
      • ViewModel (4)
      • LiveData (1)
      • Paging (0)
    • KMP (5)
    • Programming (4)
    • Machine (9)
      • JVM (7)
      • Linux (2)
    • CI, CD (74)
      • Gradle (12)
      • Groovy Gradle (5)
      • Git (25)
      • Git Remote (5)
      • GitHub (5)
      • GitHub Actions (21)
    • Network (33)
      • GraphQL (12)
      • HTTP (11)
      • Basic (9)
    • 오픈소스 (3)
    • Database (3)
      • MongoDB (3)
    • IDE (6)
      • Android Studio (2)
      • Intellij (4)
    • Firebase (1)
    • Javascript (9)

공지사항

  • 코틀린 코루틴 완전 정복 강의 in 인프런 오픈
  • 코틀린 코루틴의 정석 책 출간
  • Kotlin Coroutines 공식 기술 문서 한국어 번⋯
  • GitHub에서 조세영의 Kotlin World를 Foll⋯
  • 문의&제안

인기 글

태그

  • Dependency Injection
  • github actions
  • 의존성 주입
  • gradle
  • 코루틴
  • Kotlin
  • 스프링
  • java
  • github
  • kotlin spring
  • Coroutine
  • Spring boot
  • junit5
  • 유닛 테스팅
  • 코틀린
  • compose
  • 안드로이드
  • Android
  • junit4
  • junit
  • Unit Testing
  • Jetpack Compose
  • Spring
  • GraphQL
  • flow
  • Android Compose
  • GIT
  • HTTP
  • dagger2
  • Class

최근 글

반응형
hELLO · Designed By 정상우.v4.3.0
Dev.Cho
[Kotlin] Observer Pattern : 옵저버 패턴 알아보기
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.