👋🏻 이 글은 Reactive X, 반응형 프로그래밍을 처음 접하는 사람들을 위한 포스팅입니다.

🤔 채용공고에 보이는 의문의 자격요건

요즘 앱 개발자 포지션의 채용공고에 보면 자격요건, 우대사항 등에 다음과 같은 말들이 자주 보인다.

  • RxJava3 를 능숙하게 다룰줄 아는 사람
  • Reactive X 를 활용한 함수형 프로그래밍에 익숙한 사람
  • RxKotlin, RxAndroid 를 사용해본 적 있는 사람
  • RxSwift 를 사용하여 비동기 처리를 구현해본 사람

예상반응 1 : '뭐지? 업그레이드 된 자바인가?'
예상반응 2 : '흠.. 라이브러리 이름인가? 아무튼 좋을 듯'

RxJava, Reactive X 등 익숙하지 않은 사람들에겐 생소한 단어들이 난무한다.
Reactive X함수형 프로그래밍을 통한 비동기 데이터 흐름에 중점을 둔 패러다임
반응형 프로그래밍쉽게 적용할 수 있도록 도와주는 라이브러리다.
Reactive X 의 이름도 Reactive eXtension 에서 따온 것이다.

쉽게 말하면 효율적으로 비동기 처리를 구현하는 방법론 중 하나로 사용되는 개념이다.
언어 별로 라이브러리를 지원하기 때문에 RxJava, RxKotlin, RxSwift 등의 이름이 존재하는 것이다.
지금부터 반응형 프로그래밍이 뭔지, Reactive X 에서 사용되는 용어는 무엇이 있는지 차근차근 살펴보자.
반응형 프로그래밍이 무엇인지 알기 위해선, 우선 함수형 프로그래밍에 대해서 알아야 한다.

함수형 프로그래밍이란...?

지금까지 우리가 쓴게 함수아닌가? 그럼 우린 함수형 프로그래밍을 적용한 게 아닌가?
➡️ 당연하게도 아니다.

함수형 프로그래밍의 개념을 짚기 위해, 우리가 지금껏 사용해왔던 명령형 프로그래밍과 뭐가 다른지 알아보자.
우리가 지금까지 배웠던 절차지향, 객체지향 프로그래밍이 결국 명령형 프로그래밍의 범주에 속해있다.
아래는 이 둘의 차이점을 기술해놓은 표다.

중점적 시각 이라고 되어있는 부분을 유심히 보자.
명령형 프로그래밍은 '어떻게' 에 초점을 두고, 함수형 프로그래밍은 '무엇' 에 초점을 둔다.
이게 무슨 소리인지 쉽게 이해하기 위해 다른 분의 블로그에서 좋은 예시를 들고왔다.

정자역에서 네이버로 이동할 때, 어떻게 이동할지에 대한 방법이다.

명령형 프로그래밍의 경우

횡단보도까지 약 99m 이동(성남대로331번길) ,
횡단보도를 이용하여 경기성남분당경찰서 방면으로 횡단,
횡단보도까지 1개의 횡단보도를 지나 약 612m 이동,
횡단보도를 이용하여 메르세데스벤츠코리아더클래스효성분당전시장 방면으로 횡단,
네이버까지 약 50m 이동(불정로).

함수형 프로그래밍의 경우

출발: 정자역 주소는 경기도 성남시 분당구 성남대로 333,
도착: 네이버 주소는 경기도 성남시 분당구 불정로 6.

말 그대로, 명령형은 '이렇게' 네이버 사옥에 간다에 초점을 두고 있고
함수형은 출발지와 도착지의 주소를 입력하여 '네비게이션'을 이용한다에 초점을 두고 있다.
즉, 네비게이션에 출발지와 도착지를 입력하여 경로를 따라간다는 의미이다.

이렇게 보면, 명령형 프로그래밍의 경우 동작이 추상화가 되어있다기보다 말 그대로 네이버까지 어떻게 가는지 설명한다.
반대로 함수형 프로그래밍은 출발지로부터 도착지까지 이동하는 동작 자체가 추상화가 되어있다.
이것이 바로 함수형 프로그래밍의 핵심이다. 어떻게 동작하는지 보다 어떤 동작을 하는지 한 눈에 알 수 있게 코드 설계.
조금 과장해서 예시를 들면 return a + b + c 보다 return sum(a, b, c) 이런식으로 말이다.

근데 이게 반응형 프로그래밍이랑 뭔 상관?

처음엔 용어부터 헷갈려서 머리가 터질 수 있으니 주의해야 한다.

함수형 프로그래밍의 뛰어난 추상화 능력

함수형 프로그래밍의 추상화 개념을 더욱 극대화 하기 위해 람다함수, 고차함수 등을 지원하는 언어들이 생기기 시작했다.
즉, 함수형 프로그래밍 패러다임에선 함수 안에 함수를 선언해도 되고, 함수를 변수에, 함수의 매개변수에 넣을 수도 있다.
함수형 프로그래밍 개념에선 이러한 특성을 '함수는 일급 시민(First Class Citizen) 이다' 라고 표현한다.
(이 포스팅에선 따로 설명하지 않겠다. 기회가 되면 함수형 프로그래밍에 대해 자세히 알아보는 글을 작성해보겠다.)

이쯤에서 슬..슬 반응형 프로그래밍 얘기를 꺼내본다

반응형 프로그래밍은, 비동기적인 어떤 데이터의 흐름을 관찰하고 처리하는 기법이다.
이 익숙한 용어들만 봐도, 반응형 프로그래밍은 결코 난데없이 튀어나온 새로운 개념은 전혀 아니다.
따라서 차근차근 이해하면 그렇게 어려울 것도 없다.

우선, '비동기적인 데이터' 가 무슨 말인지 대강 예시를 짚고 넘어가보자.
흔히 말하는 비동기 처리는 프론트 엔드 / 앱 개발자 라면 꼭 알아야할 지식이기도 하다.

빠른 이해를 위해 비동기 처리를 안했을 때, 고양이 사진 DB 를 갖고있는 서버 API 호출을 통해
고양이 사진을 화면에 보여주는 서비스의 동작을 살펴보자.

이 예시는 '안드로이드 앱'에서의 시나리오라고 가정한다. 안드로이드 앱은 구동 특성상
UI 를 그리고 다양한 입출력 이벤트를 관장하는 'UI Thread' 를 메인 쓰레드로 구동하게 된다.
따라서 UI Thread 에서 Thread.sleep(5000) 을 하게 되면 5초동안 앱이 완전히 멈춘다.

따라서 UI Thread 가 API 호출을 할 때 위와 같이 비동기 처리를 하지 않는다면 만약 API 서버의 속도가 느릴 때,
UI Thread 자체가 블로킹되어 사용자의 모든 입력 동작이 씹히고 고양이 사진 목록을 가져오는 동안 앱이 멈춘다.
과장해서 서버가 너무 느려 응답시간이 몇 십초가 된다면,
사용자 입장에선 최악의 사용자 경험을 하게 될 것이다.

그러면, 이를 해결하기위해 '비동기 처리'를 적용한 시나리오를 생각해보자.

말 그대로, UI Thread 가 아닌 별도의 Thread 를 생성하고 (Thread 는 단지 여러 방법론 중 한 가지다.)
별도로 생성된 Thread 에서 서버 API 를 호출하여 고양이 사진 목록을 받아오는 동작을 하는동안
UI Thread 에서는 아무 영향 없이 원래 하던 일, 또는 다른 일 을 그대로 이어가는 것이다.

그리고 만약 API 를 호출한 Thread 에서 네트워킹 동작을 통해 고양이 사진 목록을 모두 수신 받았을 때
흔히 'Callback' 메소드를 호출하여 사진을 모두 받아왔음을 API 호출 주체 (UI Thread) 에게 알린다.
이 때 UI Thread 는 Callback 메소드를 통해 고양이 사진 목록이 완성됐음을 알게 되고,
완성된 고양이 사진 목록을 통해 UI 를 구성하면 되는 것이다.

이게 비동기 처리의 기본 개념이다. (프론트엔드 / 앱 개발자라면 익히 잘 알고 있을 것이다.)


그래서 비동기 데이터 처리가 반응형 프로그래밍이랑 뭔 상관?

다시 설명하자면, 반응형 프로그래밍은 비동기적인 어떤 데이터의 흐름을 관찰하고 처리하는 기법이다.
그럼 이제 이 '비동기 처리' 동작이라는 것이 반응형 프로그래밍이랑 무슨 상관인지 알아보자.

반응형 프로그래밍은 함수형 프로그래밍 패러다임의 근간에 의해 탄생한 기법이다.
글 초반부에서 설명한 함수형 프로그래밍의 특성은, 결국 '반응형 프로그래밍' 기법에 안성맞춤이다.

그러니까, 반응형 프로그래밍비동기적인 데이터 흐름을 관찰하고 처리를 하는 프로그래밍 기법인데
'비동기적 데이터 흐름 관찰' 동작 자체가 함수형 프로그래밍의 특성과 케미가 잘 맞는다는 뜻이다.

루루 고양이

'왜 비동기적인 데이터 흐름 처리에 있어 함수형 프로그래밍이 적합한거지?'

간단하다. 위의 예시대로, API 호출을 통해 귀여운 고양이 사진 목록을 받았다고 하자.
하지만 기획한대로라면 아기 고양이이고 색깔이 갈색인 고양이만 화면에 보여줘야 한다고 가정하자.
또한, 각각 이미지에 제목을 붙여야 하며 고양이 사진이 하나 로드될 때 화면이 반짝 거리는 이벤트와
고양이 사진이 모두 로드 됐을 때 로딩 다이얼로그가 사라지는 이벤트를 구현해야 한다고 하자.

단순한 구현으로 접근해보자면, 로드가 완료된 고양이 사진 목록을 하나씩 탐색해보면서
로딩이 완료되고 아기 고양이 사진과, 갈색 고양이 사진만을 추가한 새로운 목록을 만들면 된다.
그리고 새로운 목록이 만들어졌을 때 다이얼로그를 없애는 Callback 메소드를 구현하면 된다.
또한 생성된 새로운 이미지 목록을 for-each 로 하나하나를 탐색하며 제목을 붙여준다.
그리고 또 ... 어...

결국 코드도 난잡해지고 다른 사람이 코드를 봤을 때 어떤 동작을 하는지 눈에 잘 보이지 않게 된다.

이 복잡한 처리 동작을 놓고 봤을 때, '고양이 사진 목록' 이라는 데이터를 받아오고 처리함에 있어
필요한 모든 동작을 API를 호출하는 함수의 '매개변수' 형식으로 넘겨준다면?

훨씬 더 깔끔하게 처리할 수 있고, 이것이 말 그대로 '데이터 스트림'을 관찰하고 처리하는 것이다.

예를들어 아래와 같은 동작들이 필요할 것이다.

  • 아기 고양이 사진만 걸러주는 함수 (filter)
  • 갈색 고양이 사진만 걸러주는 함수 (filter)
  • 고양이 사진에 임의의 제목을 붙여주는 함수 (map)
  • 고양이 사진 하나가 로드될 때마다 실행될 함수 (onNext)
  • 고양이 사진이 모두 로드됐을 때 실행될 함수 (onCompleted)
  • 어떠한 오류로 고양이 사진 로드에 실패했을 때 (onError)

이렇게 다양한 함수를 매개변수로써 넘겨줄 수 있을 것이다. 동작 자체가 강력하다.
동작 각각의 오른쪽 괄호안에 뭔가를 적었는데, RxJava 에서 해당 동작을 할 수 있는 실제 메소드 명이다.
이러한 메소드 명만 봐도 데이터 흐름 동작에 어떤 동작을 수행하는지 명백하게 보이기도 한다.
(함수형 프로그래밍의 특성을 매우 잘 살리게 된다)

이러한 데이터 흐름을 만드는 함수에 다른 함수를 합성하고, 다른 함수에 의해 데이터를 필터링하고,
데이터 처리에 있어 에러를 핸들링하는 다른 함수도 넣고! 데이터가 완성되면 실행할 함수도 넣고!

이렇게 데이터를 지지고 볶는 것이 함수형 프로그래밍 기법의 특성에서 비롯된 것이다.

비동기적인 데이터 스트림이라 함은 이 예시에서의 네트워킹 (API 호출) 뿐만 아니라
사용자의 클릭 이벤트, 스크롤 이벤트 등도 모두 비동기적인 데이터 흐름으로 취급할 수 있다.

사용자가 어떤 키워드를 입력할 때, 입력이 끝나면 자동으로 해당 키워드를 통해 검색 API를 호출하는
동작 등이 모두 반응형 프로그래밍 기법으로 구현 가능하다.

따라서 비동기적으로 발생하는 데이터 흐름을 핸들링하는 동작 구현 자체가, 함수형 프로그래밍을 사용하면
훨씬 더 파워풀하고 가독성있게, 깔끔하게 데이터 흐름을 가공하고 처리하는 동작을 구현할 수 있다는 뜻이다.


🔥 처음이 어렵지, 사실은 매우 강력하다

그렇게 매우 합당한 열풍이 시작되었고, 특히 사용자와 차질없는 상호작용을 해야하는
프론트엔드, 모바일 앱 개발자들
사이에서 반응형 프로그래밍이 보편화된 것이다.

마이크로소프트에선 이를 쉽게 구현하기 위한 Reactive X 라는 라이브러리를 개발한 것이고,
언어 및 프레임워크에 따라 포팅되어 RxJava3, RxSwift3 등으로 불리게 되는 것이다.

프론트엔드, 앱 개발자들에게 비동기적인 데이터 처리는 거의 필수 영역이므로, 이러한 기법들을 잘 숙지해야
훨씬 정교하고 효율적인 비동기 처리를 구현할 수 있다. 따라서 기업들에서 반응형 프로그래밍에 익숙한 개발자들을
자격 요건으로, 우대 사항으로 제시하는 것이다.

절대 기업 입사를 위한 것이 아니다. 직접 구현해보면 정말 필요에 의한 방법론임을 느끼게 될 것이다.
반드시 꼭 반응형 프로그래밍 패러다임에 익숙해져야 할 때가 되었다.

Reactive X 라이브러리에 맞서 안드로이드에선 자체적인 라이브러리인 Coroutines Flow 라는 것이 나왔는데,
이에 대해 알아보는 글도 작성할 예정이다.

profile
어려울수록 기본에 미치고 열광하라

6개의 댓글

comment-user-thumbnail
2021년 5월 26일

유익한 정보 감사합니다 ^^

답글 달기
comment-user-thumbnail
2021년 5월 28일

루루가 너무 귀여워요 ^^

답글 달기
comment-user-thumbnail
2021년 6월 1일

좋은 글 감사합니다! 관련 내용해서 참고하신 자료있으신지 궁금합니다 :)

1개의 답글
comment-user-thumbnail
2021년 6월 3일

감사합니다! 아직 개념을 잘 못 잡았는데 좋은 참고자료가 되었네요

1개의 답글