들어가는 글: 작게나마 구구단을 Rx적으로 짜보고 다시 소강상태입니다. 앞으로 어떻게 공부하면 좋을까요?
지금까지 한 주간 달려온 것은
1) Rx(반응형 프로그래밍)이란 무엇인가?
2) 처음 Rx코딩해보기
3) for()문으로 Rx구구단 만들어보기
였습니다. 밑천이 떨어졌습니다. 길을 잃었습니다.
새로운 책을 주문했습니다.
주말에 차분하게 읽어봤는데 아직 갈길이 멉니다. 150여 페이지로 얇은 책이지만 Java8 람다 표현식도 다루고 있고 작년 6월로 비교적 최근에 나온 책입니다. 영어라는게 문제지만 기회가 되면 꼭 읽어보세요. 정리가 잘 되어 있습니다.
앞으로 어떻게 공부해볼지 생각을 해봤습니다. 당연히 모든 것을 알아야 겠지만 몇가지 길이 있습니다.
기존에는 EditText에서 input 값을 가져왔는데 안드로이드에서 활용하려면 안드로이드 Content Provider, File, 서버 등의 다른 데이터 소스에서 가져오는 방법을 알아봐야 합니다.
어려운 것은 아니지만 Observable을 내가 원하는데로 만들어보는 것이 필요합니다. 지금까지 예제에서 나온 {1,2,3.. } 이런 것들만 다룰 수는 없으니까요. Integer, String 뿐만 아니라 내가 만든 클래스에서도 값을 처리할 수 있어야 합니다.
Rx코드를 만들기 위해서는 여러가지 operators를 자유자재로 구사해야 합니다. <RxJava Essentails>에서는 '실무에서 어디에 써야할지는 모르겠지만' 여러 operators 에 대해서 다루고 있습니다.
당장 무엇을 해야할지는 모르겠지만 생각을 지평을 넓히기 위해서는 꼭 필요한 과정입니다.
공식문서에서 자세히 다루고 있습니다.
http://reactivex.io/documentation/operators.html (영어)
고급과정입니다. 결국 RxJava을 사용하는 이유는 병렬적인 코드를 작성하는 것입니다. Scheduler를 활용하여 동시성 코드를 작성하고 데이터 발생과 처리에 필요한 buffering, throttling, debouncing 등에 대한 내용입니다. (솔직히 저도 자세히는 모릅니다. 문서는 읽고 있는데 잘 와닿지는 않네요)
코드 테스팅이 필요합니다. 제가 얼핏 듣기로 rx코드는 디버깅이 어렵다고 하더라고요(제가 직접 확인한 내용은 아닙니다) 그리고 rx코드처럼 코드의 추상성이 높아질 수록 내가 짠 코드를 다른 사람이 고치는 것도 어려워진다는 얘기도 들었습니다. (이것도 진짜인지 확인해보고 싶습니다)
공식문서 내용을 바탕으로 제가 이해하고 있는 내용으로 간단히 번역해봤습니다.
최대한 제 언어로 쉽게 다시 써봤는데 도움이 되었으면 좋겠습니다.
(아래의 모든 원문/ 이미지 출처: http://reactivex.io/documentation/operators.html)
1) Observable.create() : Observables를 직접 생성하는 방법. 여기서는 onNext(), onError(), onCompleted()를 직접 호출해줘야 함
2) Observable.from() : 이미 만들어진 자료 구조(배열, List 등) 에서 Observable을 생성해줌.
- onNext() 등을 내가 호출해줄 필요는 없음
- 만약 from으로 넘겨준 자료 구조를 다른 곳에서 변경했을 때 이것이 Subscriber에게 반영되는지는 확인 필요
3) Observable.just() : 객체를 넘겨서 Observable을 생성. 인자를 9개까지 넘길 수 있음
4) Observable.range() : 연속하는 정수값으로 Observable을 생성해줌
>> 왜 이렇게 다양한 생성 방법이 있을까요? 테스트할 때는 just()나 from()이면 충분하지만 실무에서 적용하여 custom으로 만들때는 결국 create()로 만들어야 하지 않을까 하는 염려(?)가 되네요.
1) flatMap() : A Observable에서 발생(emit)시키는 내용으로 다른 B Observable을 생성함. B Observable은 여러개가 생성되는 것이 아니고 한개이며 그것이 주욱 발생함(이것을 flatten이라고 표현하는 듯)
위의 내용을 코드로 표현하면
Observable.from(원본 데이터)
.flatMap(동그라미 -> 다이아몬드2개)
이때 녹색 다이아몬드가 1개만 출력되고 두번째 녹색 다이아몬드가 출력되기 전에 파랑 다이아몬드가 새치기 한것을 끼어들기(interleaving)이라고 합니다. flatMap()은 끼어들기를 허용합니다.
2) map() : A item을 B item으로 변환. 가장 직관적인 변환 operators. 당연히 람다 같은 함수롤 변환식으로 넣을 수 있음
이것을 코드로 표현하면
Observable.from(원본 데이터)
.map(숫자 -> 숫자 * 10)
입니다. 이때 "숫자 -> 숫자 * 10"이 매핑할 람다식입니다.
그외 buffer / groupBy / scan / window 등의 연산자들이 있는데 좀더 공부후에 사레와 함께 알아보겠습니다.
필터링은 결국 걸러내는 것입니다. 어떤 기준을 제시하고 원본 데이터의 값들이 그것에 맞는지(true) 아닌지(false)를 알아내는 것이죠. 객체가 아니라 람다 표현식을 넘겨서 판단하면 됩니다.
1) distinct : 중복되는 값을 제거하기
2) elementAt : Observables로 부터 발생하는 N 번째의 값만 가져오기
3) filter : 내가 제시한 기준에 맞는 값만 가져오기
이것을 코드로 표현하면
Observable.from(원본 데이터)
.filter(숫자 -> 숫자 > 10)
입니다. 단순한 내용입니다.
4) take : Observable에서 발생하는 N 개의 데이터만 가져오기
이것을 코드로 표현하면
Observable.from(new Integer[]{1,2,3,4})
.take(2)
그외 debounce , first(처음만) , ignoreElements, last(마지막만), sample, skip(최초 N개 건너뛰기), skipLast(마지막 것만 건너뛰기), takeLast(마지막만 가져오기) 등이 있습니다.
생성 / 변환 / 필터링 연산자 까지가 Rx 초보 과정입니다.
그 다음에는
1) 결합 연산자 - combineLast , join , merge , zip 등
2) 오류 처리 연산자 - catch, retry 등
3) 유틸리티 연산자 - delay, do, materialize(dematerialize), observeOn, serialize, subscribeOn, timeInterval, timeout, timestamp, using 등
4) 분기 연산자 - all, amb, contains, defaultIfEmpty, sequenceEqual, skipUtil, skipWhile, takeUntil, takeWhile
5) 수학과 집합 연산자 - average, concat, count, max, min, reduce, sum 등
6) Backpressure 연산자들
7) 연결형 연산자 - connect , publish, refCount, replay 등
8) Observable을 변환하는 연산자 - to 등
Rx코드는 함수형 프로그래밍을 지향합니다. 함수형 프로그래밍에는 클래스가 없습니다. 오직 함수만이 있을 뿐이죠. 이렇게 수많은 연산자가 있는 이유, 그리고 이것을 공부해야 하는 이유는..
그렇지 않으면 현업에서 직접 연산자를 만들어야 하기 때문입니다.
내장된 연산자를 공부해야 하는 것이 Rx를 공부하는 큰 진입장벽인 것이 사실입니다.
물론 그림으로 최대한 쉽게 표현하고 있지만 우리가 명령형 프로그래밍에서 다루었던
if , for, while 등의 제어문에 비하면 무지 복잡합니다.
가능하면 예제 코드도 짜보고 함께 공유하도록 하겠습니다.
긴 글 읽어주셔서 감사합니다.
2016.9.25 @Home