반응형 프로그래밍 톺아보기
💡 Notice
반응형 프로그래밍을 이해하기 위해 아등바등댄 필자의 생각 정리가 담긴 글입니다. 따라서, 여타 잘 정리된 블로그들과 관점이 다를 수 있습니다.
반응형 프로그래밍의 사전식 의미를 먼저 살펴보면, 데이터의 흐름과 데이터의 변경에 대한 전파에 중점을 두어 프로그램을 동작시키는 패러다임이다.
데이터의 흐름이란 뭐고 변경에 대한 전파는 또 무엇인가? 정의만 보고선 감을 잡기가 힘들다. 차근차근 알아가보도록 하자.
등장배경
모든 프로그래밍 패러다임은 기존의 한계점을 해결하거나 더 나은 방법을 제시하면서 탄생하였다. 반응형 프로그래밍 또한 그렇게 시작되었는데 대표적으로 다음과 같은 고민을 해결하기위해 등장하게 되었다.
- 빠른 UI 업데이트
UI는 사용자와 상호작용하기 때문에 빠르게 반응을 해야한다. 따라서, UI와 관련된 데이터가 변경되었을때 즉시 처리되어야 한다. 기존에는 행위에 대한 결과를 받은 후 UI 변경에 대한 로직을 직접 처리해야하는 등 코드의 복잡도가 높아졌다. 따라서, 데이터의 변경을 관찰하여 변경시 즉시 반영하고자하는 움직임이 일었다. - 복잡한 비동기 프로그래밍 처리
대부분의 프로그래밍에서 비동기 프로그래밍은 필수적이다. 하지만 비동기 이벤트는 작업 완료시점을 미리 예측할 수 없다는 단점이 있다. 비동기 작업 도중 프로그램을 멈출수는 없으니 이후 처리를 위해 콜백 함수를 사용하였지만, 연속적인 비동기 작업 처리 시 코드의 복잡도가 증가하였고, 작업간 의존성이 높아지는 문제가 발생하였다.
비동기 프로그래밍은 그 작업흐름을 파악하기 힘들기 때문에 작업 결과를 처리를 위해 콜백 함수를 넘겼다. 이는 작업처리와 결과처리 사이에 의존성이 생기게 된다. 이를 해결하기 위해 데이터의 흐름을 스트림(Stream)으로 추상화화고 변경사항을 전파하는 방식을 채택하였다.
데이터의 흐름을 스트림으로 추상화
데이터의 흐름이란 작업을 시작하는 시점부터 결과를 받는 시점까지의 과정을 의미한다. 네트워크 통신을 예로 들자면, 서버로 요청을 시작하는 시점부터 응답을 받는 시점까지의 과정을 뜻한다.
그리고 이러한 과정자체를 하나의 흐름으로 생각하고 이 흐름을 스트림(Stream)으로 추상화해서 표현한다. 쉽게 말해 과정을 추상화한 컨테이너라고 볼 수 있다. 이는 매우 큰 장점을 가지는데 비동기 작업이든 동기 작업이든 똑같은 하나의 스트림으로 취급이 가능해진다는 점이다. 즉, 비동기 작업이 가지는 예측불가, 코드의 복잡성, 의존문제를 해결할 수 있다.
스트림 덕분에 의존성을 분리할 수 있어 결합도가 낮아지며, 과정을 추상화함으로써 코드는 간결해지고 가독성이 높아진다.
분리한 것까지 좋은데 응답값에 대한 결과처리를 어떻게 해주는 걸까? 이것은 스트림의 또다른 기능인 자동전파를 통해 이루어진다.
💡 Stream(스트림) 구현하기
과정을 추상화한 스트림을 구현해도 좋지만 이미 잘 만들어진 라이브러리들이 존재한다. 대표적으로 ReactiveX에서 각 언어별로 스트림과 반응형 프로그래밍을 구현할 수 있도록 라이브러리를 만들어놨다. 또한 iOS에서는 자체적으로 Combine Framework를 지원한다.
변경내용을 자동으로 전파하자
보통 하나의 과정만으로 프로그램이 동작하지 않는다. 한 과정의 결과값으로 또 다른 과정이 동작한다. 반응형 프로그래밍에서는 과정을 스트림을 추상화하였다. 그렇다면 한 과정의 결과값을 어떻게 사용할까? 바로 구독과 전파방식을 사용한다. 위에서 설명한 네트워크 스트림은 결과값을 내뿜는다. 이렇게 결과를 내뿜는 스트림들(생산자 스트림)을 결과값을 처리하는 스트림들(소비자 스트림)이 관찰할 수 있는데 이를 구독한다고 표현한다. 생산자 스트림에서 데이터가 갱신된다면 자신을 구독하고 있는 스트림들에게 갱신된 데이터를 자동으로 전파를 한다. 이를 통해 여러 스트림들이 연쇄적으로 동작하게 된다.
Pull방식이 아닌 Push(전파) 방식으로의 전환은 다음과 같은 이점을 얻을 수 있다.
- 제어의 역전
명시적인 요청이 없어도 데이터 전달, 각각의 독립성이 보장됨 - 코드의 간결성
수동으로 데이터 전달, 이후 실행시킬 로직을 따로 작성하지 않으므로 코드의 간결성이 높고 오류가 줄어든다. - 성능 향상
데이터 갱신시 즉시 전송으로 소비측은 대기 하지 않고 갱신시에 처리함으로 속도가 빨라진다. - 예측 가능성
데이터가 언제 전송될지를 미리 예측가능한다. 이는 디버깅, 유지보수, 테스트를 용이하게 만든다.
++ 선언적 프로그래밍과 함수형 프로그래밍
반응형 프로그래밍은 과정보다는 결과에 초점을 맞추는 선언적 프로그래밍 방식을 채택했다. 앞서 보았듯이 과정을 스트림으로 추상화함으로써 구현에 대한 에러를 최소화하고 가독성과 유지보수성을 향상시켰다.
또한 반응형은 스트림을 조작하기 위해서 다양한 연산자를 사용 할 수 있다. 연산자들은 데이터 스트림을 변환, 조합하는 등의 작업을 수행한다. 이러한 부분을 함수형 프로그래밍을 이용해 작성할 수 있으며 이를 통해, 부작용을 최소화하고 코드의 테스트 용이성을 높일 수 있다.
댓글남기기