IMCAT.DEV
로그인 가입
Scala 고급 비동기

Scala 리액티브 프로그래밍

Scala 리액티브 프로그래밍 — 고급

리액티브 프로그래밍

1. 도입 (왜 배워야 하는가)

리액티브 프로그래밍은 현대 소프트웨어 개발의 중요한 패러다임 중 하나입니다. 특히 대규모 애플리케이션이 요구하는 높은 성능과 사용자 경험을 제공하기 위해 필요합니다. 전통적인 프로그래밍 방식은 요청-응답 패턴에 의존하여 동기적으로 작동하지만, 리액티브 프로그래밍은 비동기적이고 이벤트 기반으로 작동하여 리소스를 효율적으로 사용할 수 있게 해줍니다.

리액티브 프로그래밍을 모르면 다음과 같은 문제가 발생할 수 있습니다:

  • 확장성 부족: 많은 사용자의 요청을 동시에 처리할 수 없어 시스템이 느려지거나 다운될 수 있습니다.
  • 응답성 저하: UI가 멈추거나 반응이 느려져 사용자 경험이 떨어질 수 있습니다.
  • 복잡한 에러 처리: 비동기 작업에서 발생하는 예외를 처리하기 어려워질 수 있습니다.
  • 2. 핵심 개념 설명

    리액티브 프로그래밍의 핵심 개념은 다음과 같습니다:

    개념설명
    Observable데이터의 스트림을 표현합니다. 데이터의 변화를 구독할 수 있습니다.
    ObserverObservable에서 발생하는 이벤트를 수신합니다.
    SubscriptionObservable와 Observer의 연결을 나타냅니다.
    Backpressure소비자가 생산자보다 느릴 때, 데이터 흐름을 조절하는 메커니즘입니다.

    비유하자면, Observable은 라디오 방송국, Observer는 그 방송을 듣는 청취자, Subscription은 방송을 듣기 위해 연결한 것과 같습니다. 청취자는 방송국에서 송출하는 내용을 실시간으로 듣고, 방송국은 청취자가 얼마나 많은 정보를 소화할 수 있는지를 고려해야 합니다.

    3. 기본 코드 예제

    리액티브 프로그래밍의 기본적인 사용법을 보여주는 코드입니다.

    import rx.Observable
    
    // Observable 생성
    val observable = Observable.create[Int](subscriber => {
  for (i <- 1 to 5) {
        subscriber.onNext(i)  // 데이터 전송
      }
      subscriber.onCompleted() // 작업 완료 알림
    })
    
    // Observer 생성
    val observer = new Observer[Int] {
      override def onNext(value: Int): Unit = println(s"Received: $value")
      override def onError(e: Throwable): Unit = println(s"Error: ${e.getMessage}")
      override def onCompleted(): Unit = println("Completed!")
    }
    
    // Subscription
    observable.subscribe(observer)

    실행 결과

    Received: 1
    Received: 2
    Received: 3
    Received: 4
    Received: 5
    Completed!

    코드 한 줄씩 동작 설명

    1. Observable.create[Int]를 호출하여 Observable을 생성합니다. 이 Observable은 Int 값을 방출합니다.
    2. for (i <- 1 to 5) 루프를 통해 1부터 5까지의 값을 생성합니다.
    3. subscriber.onNext(i)를 통해 각 값을 Observer에 전달합니다.
    4. 모든 값이 전송된 후, subscriber.onCompleted()로 작업이 완료되었음을 알립니다.
    5. observable.subscribe(observer)를 통해 Observer가 Observable을 구독합니다.
    6. 4. 실전 활용 예제

      1. 쇼핑몰 장바구니 구현

      쇼핑몰에서 장바구니에 상품을 추가할 때, 사용자가 추가하는 즉시 UI에 반영되도록 할 수 있습니다.

      import rx.subjects.PublishSubject
      
      val cartSubject = PublishSubject.create[String]()
      
      // 장바구니에 상품 추가
      cartSubject.subscribe(item => println(s"Item added to cart: $item"))
      
      // 상품 추가
      cartSubject.onNext("Laptop")
      cartSubject.onNext("Smartphone")

      상황 설명 사용자가 상품을 장바구니에 추가하면, 해당 상품이 즉시 출력됩니다. 이로 인해 사용자에게 실시간 피드백을 제공할 수 있습니다.

      2. 실시간 데이터 스트리밍

      서버에서 실시간으로 데이터를 수신하고 이를 UI에 반영하는 예입니다.

      import rx.Observable
      
      val dataStream = Observable.interval(1.second).map(tick => s"Tick: $tick")
      
      dataStream.subscribe(data => println(data))

      상황 설명 이 코드는 1초마다 "Tick" 메시지를 출력합니다. 이러한 방식으로 실시간 데이터를 처리할 수 있습니다.

      5. 흔한 실수와 주의사항

      흔한 실수

    7. Observer를 구독하지 않음
    8. - 잘못된 코드:

           observable // 구독하지 않음

      - 올바른 코드:

           observable.subscribe(observer) // 구독 필요
    9. 생산과 소비의 불균형
    10. - 잘못된 코드:

           observable.map(x => / heavy computation /) // 느린 소비

      - 올바른 코드:

           observable.buffer(10) // 배치 처리하여 성능 개선

      6. 정리

    11. 리액티브 프로그래밍은 비동기적이고 이벤트 기반의 프로그래밍 모델입니다.
    12. Observable, Observer, Subscription 등이 핵심 개념입니다.
    13. 실시간 데이터 처리 및 UI 반영에 유용합니다.
    14. 다음에 학습하면 좋은 주제: Akka Streams 또는 Monix와 같은 리액티브 라이브러리.