ReactiveX란 무엇인가?

이정훈·2024년 2월 23일
1

ReactiveX

목록 보기
1/5
post-thumbnail

ReactiveX란 무엇인가❓

RxSwift 사용법을 알아보기 이전에 ReactiveX란 무엇인지 알아보자

ReactiveX, 혹은 Reactive Extension, 또는 줄여서 Rx라고도 불리는데 지금부터 편하게 Rx라고 통칭하겠다. Rx는 마이크로소프트에서 개발한 비동기 이벤트를 핸들링 해주는 오픈소스 라이브러리이다. 정확히 말하면 Rx 공식 홈페이지에서는 다음과 같이 소개하고 있다.

An API for asynchronous programming
with observable streams

👀 Observer 패턴

Rx에서는 비동기 이벤트 핸들링을 위해 Observer(옵저버) 디자인 패턴을 사용하고 있는데 간단히 말하자면..

Observer 패턴이란 관찰자(옵저버)관찰 대상이 되는 객체를 등록 함으로서 해당 객체의 상태 변화를 관찰하고 관찰 대상인 객체가 상태 변화로 이벤트를 발생 시킬때, 이 이벤트를 감지하여 처리한다.

이러한 Observer 패턴은 네트워크 통신과 같은 비동기 이벤트와 함께 사용할 때 좋은 궁합을 보여주는데, 네트워크 통신과 같이 처리하는 데 비교적 시간이 오래 걸려 값이 미래에 준비되는 상황에서 값이 준비될 때까지 대상을 관찰하다가 값이 도착했을 때 값이 도착한 것을 감지하고 처리할 수 있다.

Rx에서는 이러한 관찰자Observer 그리고 관찰 가능한 대상Observable이라고 한다.

🙋‍ 비동기 이벤트 처리는 옵저버 패턴이 아니라도 기존의 탈출 클로저로도 가능한거 아닌가요?

탈출 클로저로도 비동기 이벤트를 처리할 수 있는데, 탈출 클로저의 가장 큰 단점은 연쇄적인 비동기 이벤트가 발생 하였을 때 중첩된 형태의 클로저는 코드의 가독성 저해개발자의 실수를 유발 시키는 요인이 된다고 생각한다.

일명 콜백 지옥.

Rx비동기 이벤트 핸들링을 위한 좀 더 간단하고 강력한 기능을 제공하는데, RxObservable은 데이터 변화에 대한 값을 방출하는 data flow 즉, Stream을 만들어 낼 수 있다.

이러한 Stream은 데이터를 전달할 수 있는 통로를 만들어 Observer에게까지 전달될 수 있도록 한다. Rx가 좀 더 강력한 기능을 제공할 수 있는 이유는 Stream을 통과 하면서 다양한 Operator(연산자)를 거치면 데이터를 입맛에 맞게 조작하거나 변형을 가하여 Observer에게 전달될 수 있기 때문이다. (자세한 용어는 다음 포스트에서 더 정확하게 다룰 예정)

𝒇 함수형 패러다임

본 게시물이 함수형 패러다임에 대한 이야기를 집중적으로 다루고 있지는 않으므로 간단히 말하자면..

함수형 패러다임에서 함수는 하나의 일급 객체로서 변수상수에 함수를 할당 가능하고 다른 함수의 전달인자로서 매개변수에 전달 가능하다.

갑자기 왜 함수형 패러다임을 이야기 하는가 하면, Rx를 좀 더 강력하게 만드는 기능 중 하나가 바로 이 함수형 패러다임과의 조합이다.

가령, 비동기 네트워크 통신으로 서버로부터 데이터를 가져온 상황을 가정해 보자. 우리는 서버로부터 가져온 raw한 데이터를 사용자의 입맛에 맞게 가공하려고 한다.

  • 사용자에게 불필요한 정보들은 걸러낸다 (filter)
  • 가져온 데이터를 다른 데이터 타입으로 변환한다 (map)
  • 데이터를 하나 받은 후 어떤 동작을 수행한다 (onNext)
  • 네트워크 통신이 완료된 후에 어떤 동작을 수행한다 (onComplete)
  • 네트워크 통신에 실패한 경우에 어떤 동작을 수행한다 (onError)

위의 과정은 하나의 stream을 만들어 내고, 이러한 연속적인 Operator의 적용은 함수의 연쇄적인 체이닝을 통해 구현할 수 있으며, stream선언적으로 표현할 수 있도록 한다. 다시 말해 Rx는 이러한 함수형 패러다임과 찰떡 궁합이라고 할 수 있다.

아래 코드는 Rx에서 함수의 연쇄적인 체이닝을 보여주는 예시이다.

import RxSwift

let disposeBag = DisposeBag()

Observable.from([1, 2, 3, 4, 5, 6, 7, 8, 9])
    .filter {
        $0.isMultiple(of: 2)    // 짝수만 걸러냄
    }
    .map {
        String($0)    //문자열로 변환
    }
    .subscribe(onNext: { number in
        print(number)
        //2
		//4
		//6
		//8
    })
    .disposed(by: disposeBag)

Rx에서는 위의 예시로 나온 Operator 말고도 더 다양한 Operator를 지원하고 있으며, 앞으로 게시물을 작성하면서 다양한 Operator에 대해 알아볼 예정이다.

💡 반응형 프로그래밍

Rx에서는 Observer 패턴을 사용하면서 반응형 프로그래밍을 가능하게 한다.

Reactive Programming(반응형 프로그래밍)은 모든 것을 데이터 스트림으로 간주하고, 데이터(이벤트)에 따라 변경 내용을 전파하는 프로그래밍 방식을 말한다.

기존 명령형 프로그래밍과의 차이를 살펴보도록 하자.

먼저 아래의 코드는 기존의 명령형 프로그래밍에서 사용하던 방식이다.

var numA: Int = 1
var numB: Int = 2
var numC = numA + numB

print(numC)    //3

numA = 5
print(numC)    //3

numC의 값은 numAnumB의 값의 합으로 구성된다. 기존의 명령형 프로그래밍에서는 중간에 numA의 값이 변경 되어도 numC에 값을 재할당하지 않는 이상 값이 변하지 않는 것을 알 수 있다.

위의 코드는 Rx를 이용하여 반응형 프로그래밍 방식으로 구현하면 어떻게 될까?

import RxSwift
import RxRelay

let a = BehaviorRelay(value: 1)
let b = BehaviorRelay(value: 2)
var c: Int = a.value + b.value

Observable.combineLatest(a, b) { $0 + $1 }
    .subscribe(onNext: {
        c = $0
    })

print(c)    //3

a.accept(5)
print(c)    //7

자세한건 다음 게시물에서 살펴 보고 간단히 느낌만 보고 가도록 하자. combineLatestab에 이벤트(값의 변경)가 발생할 때마다 c에 값이 할당 되도록 하고 있다. 따라서 처음 c를 출력할 때는 12의 합인 3이 출력되고 이후에 a의 값이 5로 변경되고 난 후에 c를 출력할 때는 결과 값이 7로 출력되는 것을 볼 수 있다.

반응형 즉, 위의 예시대로라면 a 값의 변화에 따라 반응하여 c의 값이 바뀐다는 것이다.

Rx의 가장 큰 장점은 비동기와 이벤트가 stream으로 흐른다는 것이다. 위에서 언급한 비동기 네트워크 통신 외에도 사용자의 버튼 클릭, 텍스트 입력 등과 같은 이벤트도 하나의 stream로 취급하여 상태 변화를 쉽게 관찰할 수 있게 해준다.

예를 들어 사용자가 텍스트를 입력하여 검색 결과를 화면에 보여주는 상황을 생각해보자. 사용자 입력을 감지하여 입력을 들어올 때마다 입력 됐음을 감지하고 입력된 값을 다시 비동기 네트워크 통신을 통해 결과 값을 가져오고, 가져온 값을 다시 화면에 표시해주는 일련의 과정이 Rx를 사용하면 반응형 프로그래밍 방식으로 쉽게 구현이 가능하다는 것이다.

이어지는 게시물부터 어떻게 이벤트를 통해 stream를 생성하고 관찰할 수 있는지에 대해 알아보겠다.

Reference

https://academy.realm.io/kr/posts/reactive-programming-with-rxswift/

https://velog.io/@haero_kim/Android-%EB%8C%80%EC%B2%B4-%EC%82%AC%EB%9E%8C%EB%93%A4%EC%9D%B4-RxJava-%EA%B1%B0%EB%A6%AC%EB%8A%94-%EA%B2%8C-%EB%AD%90%EC%95%BC-Reactive-X-%EB%8B%A8-%EB%B2%88%EC%97%90-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0

profile
새롭게 알게된 것을 기록하는 공간

0개의 댓글