- Rx Java ๋ฑ์ฅ ๋ฐฐ๊ฒฝ 1.1. ๋๊ธฐ/๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ 1.2. ๋ช ๋ นํ ํ๋ก๊ทธ๋๋ฐ 1.3. ํจ์ํ ๋ฐ์ ํ๋ก๊ทธ๋๋ฐ 1.4. ์์
- Rx Java์ ํน์ง 2.1. ์ฅ์ 2.2. ๋จ์ 2.3. ์์ ์ฝ๋, ์ฝ๋ ๋น๊ต
- ์ฌ์ฉ๋๋ ๊ณณ
- ์กฐ๊ธ ๋ ์์ธํ!! 4.1. ์ดํด๋ฅผ ๋๊ธฐ์ํด ์์ ๋ ๊ฒ 4.1.1. observer pattern 4.1.2. Iterator pattern 4.1.3. Functional programming (1.3. ํจ์ํ ๋ฐ์ ํ๋ก๊ทธ๋๋ฐ) 4.1.4. MVVM model 4.1.5. Dataflow programming 4.2. ๊ธฐ๋ณธ์ ์ธ ๋น๋ฉ ๋ธ๋ก 4.2.1. Observable 4.2.2. Subscriber 4.3. ์์ฃผ ์ฌ์ฉํ๋ ํจ์
- ์ฝ๋ ์ฝ์ด๋ณด๊ธฐ
5.1
๊ตฌ๊ตฌ๋จ ์ฝ๋ - ๋ ํผ๋ฐ์ค
๋ ๋์๊ฐ ๋ณด๊ธฐ
Rx Java๋ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ฃผ๊ธฐ ๋๋ฌธ์ ์ต๊ทผ 2๋ ๊ฐ ๊ธ ๋ถ์ ์ค์ ๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์์ผ๋ก๋ ์ด๋ป๊ฒ Rx Java๊ฐ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ํด๊ฒฐํด ์ค ์ ์๋์ง ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ฐ์ ์๋๋ก์ด๋ ์คํ๋์ค์์ ๊ธฐ์กด์ ์ฌ์ฉํ๋ ์ธ์ด๋ Java์ ๋๋ค. Java, C#, C++ ๋ฑ์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ๋๋ถ๋ถ ๋ช ๋ นํ ํ๋ก๊ทธ๋๋ฐ์ ์ง์ํ๊ธฐ ์ํด ๋์์ธ ๋์์ต๋๋ค. ํ์ง๋ง ์ง๊ธ ๊ณต๋ถํ๋ ค๋ Rx Java๋ ํจ์์ ๋ฐ์ ํ๋ก๊ทธ๋๋ฐ์ ๋ฐฉ๋ฒ์ด๋ฉฐ ๋ฆฌ์กํฐ๋ธ ํ๋ก๊ทธ๋๋ฐ(Reactive Programming)์ผ๋ก ๋น๋๊ธฐ ๋ฐ์ดํฐ ํ๋ฆ์ ๊ธฐ๋ฐ์ ๋ ํจ๋ฌ๋ค์์ ๋๋ค.
- ๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ : ์์ ์ ํ๋ ์ํํ ๋, ๊ทธ ์์ ์ด ๋๋๊ธฐ ์ ๊น์ง ๋ค๋ฅธ ์์ ์ ์ํํ์ง ๋ชปํ๋ ๋ฐฉ์์ ํ๋ก๊ทธ๋๋ฐ์ ๋ปํฉ๋๋ค.
- ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ : ์์ ์ ์์ฒญ ํ ํ์, ๊ทธ ๊ฒฐ๊ณผ๊ฐ ๋์ค์ง ์์๋๋ผ๋ ๋ค๋ฅธ ์์ ์ ์ํํ ์ ์๋ ๋ฐฉ์์ ํ๋ก๊ทธ๋๋ฐ์ ๋ปํฉ๋๋ค.
๋ช ๋ นํ ํ๋ก๊ทธ๋๋ฐ์ ์ฌ์ฉ์๊ฐ ์ํ๋ ๋์์ ํ๋์ฉ ํ๋์ฉ ํ๋ก๊ทธ๋๋ฐ ํ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋งค์ฐ ๊ตฌ์ฒด์ ์ด๊ณ ์์ธํ๊ณ ๋์ ํ๋ํ๋์ ์ฝ๋๋ฅผ ์์ฑํด์ผํฉ๋๋ค. ์ด๋ '์ด๋ค ๋ฐฉ๋ฒ'์ผ๋ก ๋ฌด์ธ๊ฐ๋ฅผ ํ ์ง๋ฅผ ์ค์ฌ์ผ๋ก ํ๋ ํ๋ก๊ทธ๋๋ฐ์ ๋๋ค.
๋ช ๋ นํ ํ๋ก๊ทธ๋๋ฐ์ด๋ ๊ทธ๋ ๋ค๋ฉด ๋ช ๋ นํ ํ๋ก๊ทธ๋๋ฐ์์๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๋ค๋ ์๋ฌธ์ด ๋ค ์๋ ์์ต๋๋ค. ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ ๊ฐ๋ฅํ๋ค๊ณ ํ์ง๋ง ๋ช ๋ นํ ํ๋ก๊ทธ๋๋ฐ์ ๊ฒฝ์ฐ์๋ ์ํ ๋ณ๊ฒฝ์ ์ค์๋๊ฐ ๋๊ณ ์์ ์ ์คํํ๋ ์์์ ์ค์๋ ์ญ์๋ ๋๊ธฐ ๋๋ฌธ์ ์ฝ๊ฒ ์ํ๋ฅผ ๋ณ๊ฒฝํ๊ธฐ๊ฐ ์ด๋ ต์ต๋๋ค. ๋ฐ๋ผ์, ๋ช ๋ นํ ํ๋ก๊ทธ๋๋ฐ์ ๋น๋์ฒ๋ฆฌ๊ฐ ์ด๋ ต๋ค๋ ๊ฒฐ๋ก ์ ๋ผ ์๊ฐ ์์ต๋๋ค.
๋ช ๋ นํ์ด ์๋ ์ ์ธํ์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ๋ฒ์ด ๋ฐ๋ก ํจ์ํ ๋ฐ์ ํ๋ก๊ทธ๋จ์ ๋๋ค.
ํจ์ํ ๋ฐ์ ํ๋ก๊ทธ๋๋ฐ์ ์ํ ๋ณ๊ฒฝ์ ์ค์๋์ ์คํ ์์์ ์ค์๋๊ฐ ๋ฎ์ต๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ ์ฐจ์ ์ผ๋ก ์์ ์ด ์ํ๋์ง ์๊ณ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ์์ํ ์ ์์ต๋๋ค.
-
๋ช ๋ นํ ํ๋ก๊ทธ๋๋ฐ <์์ ์ ์์ ์ง์์ ์์ ์ถ๋ ฅ>
Using System; using System.Collections.Generic; namespace _01_Even_and_Prime { class Program { static void Main(string[] args) { int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; Print("All:", numbers); Print("Evens:", GetEvens(numbers)); Print("Primes:", GetPrimes(numbers)); } public static void Print(string label, int[] source) { Console.WriteLine(label); foreach (int item in source) Console.Write(" {0}", item); Console.WriteLine(""); } static int[] GetEvens(int[] numbers) { List result = new List(); if (numbers != null) { foreach (int number in numbers) { if ((number % 2) == 0) result.Add(number); } } return result.ToArray(); } } }
Console Result All : 1 2 3 4 5 6 7 8 9 10 Evens : 2 4 6 8 10
์ง์๋ GetEvens ํจ์์์ ๋ ๋ฆฝ์ ์ผ๋ก ๊ตฌํ๋์ด์๊ณ ์ฌ์ฌ์ฉ๋๋ ์ฝ๋๊ฐ ์๋ค. ์ด๋ป๊ฒ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ง๋ฅผ ๊ตฌ์ฒด์ ์ผ๋ก ๊ธฐ์ ํ๊ณ ์์ต๋๋ค.
-
ํจ์ํ ๋ฐ์ ํ๋ก๊ทธ๋๋ฐ <์ง์ ๊ตฌํ๊ธฐ>
[1 .. 15] |> List.sortBy(fun x -> -x) |> List.filter(fun x -> x % 2 = 0) |> List.iter(printfn "%d")
โ|>โ๋ ํ์ดํ๋ผ์ธ ์ฐ์ฐ์์ด๋ฉฐ List์ sortBy, filter, iter ํจ์๋ ํจ์๋ฅผ ์ธ์๋ก ๋ฐ์ ์ ์๋ ๊ณ ์ฐจ ํจ์์ด๋ค. ์ธ์๋ก ์ ๋ฌํ ํจ์๋ ๋๋ค ํํ์์ ๋ํ๋ด๋ fun์ ์ด์ฉํด โx -> -xโ์ โx -> x % 2โ๋ฅผ ์ ๋ฌํ๊ณ ์์ต๋๋ค.
๋์ ์ถ์ํ ์ ๊ณต
์ฐ์ ๋ช ๋ นํ ํ๋ก๊ทธ๋๋ฐ์ ๋ ์ด์ ๊ฐ์ ํ๊ธฐ ํ๋ ์ฌ๋ฌ๊ฐ์ง ํ์์ ๊ฐ์ ํ ์ ์๋ค๋ ์ ์์ Rx Java๋ฅผ ๋์ฌ๊ฒจ ๋ณด์์ผ ํ๋ค๊ณ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด๋ณด์๋ฉด, ๋ชจ๋ฐ์ผ ์ฌ์ฉ์๋ค์ด ์ํ๋ ์ฆ๊ฐ์ ์ธ ๋ฐ์์ ์ํฉ๋๋ค. ํ์ง๋ง ์๋๋ก์ด๋ ๋ด๋ถ์์๋ ์ฌ๋ฌ ์ฐ๋ ๋๋ฅผ ์ฎ๊ฒจ ๋ค๋๋ฉด์ ์คํํด์ผ ํ๊ธฐ๋๋ฌธ์ ์ฆ๊ฐ์ ์ธ ๋ฐ์์ด ์ด๋ ค์ด ๊ฒฝ์ฐ๊ฐ ๋ง์ด ์์ต๋๋ค. ํ์ง๋ง Rx Java์ ๊ฒฝ์ฐ์๋ ์ฐ๋ ๋ ๊ฐ์ ์ ํ์ด ์ฝ๊ธฐ ๋๋ฌธ์ ์ด์ ์ข์ ๋์ฒด ๋ฒ์ด ๋ ์ ์์ต๋๋ค.
๋ํ, Operator๋ค์ ์กฐํฉ์ผ๋ก ์ํฉ์ ํด๊ฒฐํ๊ธฐ ๋๋ฌธ์ ์ฐ์์ ์ธ API ํธ์ถ์์ Rx Java์ ์ ์ฐํจ์ ๋ณด์ฌ ์ค ์ ์์ต๋๋ค. ํธํ๊ฒ ํ๋ฆ์ ํ์ ํ ์ ์์ผ๋ฉฐ, ๊ตฌํ ์ญ์๋ Java์์ Async Task์ ๋น๊ตํ๋ค๋ฉด ํจ์ฌ ๊ฐ๊ฒฐํ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
Rx Java๋ ์ฐ์ ์ง์ ์ฅ๋ฒฝ์ด ๋์ ํธ์ ๋๋ค. Rx Java ๋ฟ๋ง์ด ์๋๋ผ, Java๋ C++๋ฑ์ ๋ช ๋ นํ ํ๋ก๊ทธ๋๋ฐ์ ์ต์ํด์ ธ์๋ ์ฐ๋ฆฌ์๊ฒ ํจ์ํ ๋ฐ์ ํ๋ก๊ทธ๋๋ฐ ์์ฒด๊ฐ ์ต์ํ์ง ์์ ์ ๋ฐ์ ์์ต๋๋ค.
๋ฐฐ์ฐ๋ ๊ฒ์ด ์ด๋ ต๊ธฐ ๋๋ฌธ์ ํ์ต๋น์ฉ์ด ๋ง์ด ๋ค์ด ํฐ ์ต์ํ์ง ์์ ์ฌ๋๋ค์ด ์งํํ๋ ํ๋ก์ ํธ์ Rx Java๋ ์ ํฉํ์ง ์์ ์ ์์ต๋๋ค.
ํ์
์์ ์ผํ์๋ ๊ฐ๋ฐ์ ๋๋ค๋ ๊ฐ๋
์ ์๋ฒฝํ ์ดํดํ์๋๋ฐ 6๊ฐ์์ด ๊ฑธ๋ฆฌ์
จ๋ค๋ ์๋ฆฌ๊ฐ...
๊ฐ์ ๋ ์ํฉ : ๊ฐ์์ ์๋ฒ์ User API๋ฅผ ํธ์ถํ ๋ค์, ๊ทธ ์ฌ์ฉ์์ ID๊ฐ์ ๋ค์ ์๋ฒ์ ๋ณด๋ด์ ์ ํจํ ์ฌ์ฉ์์ธ์ง ์๋์ง ์์์ผํ๋ ์ํฉ์ ๋๋ค.
<Async Task๋ฅผ ์ฌ์ฉํ ์ฐ์๋ ๋คํธ์ํฌ ํต์ >
public class GetUserAsyncTask extends AsyncTask {
doInBackground() {
//โฆ network logic
return user;
}
onPostExecute(User user) {
new ValidUserAsyncTask(user).execute();
}
}
public class ValidUserAsyncTask extends AsyncTask {
public ValidUserAsyncTask(User user) { }
doInBackground() {
//โฆ more network logic
return isUserValid;
}
onPostExecute(boolean isUserValid) {
isUserValid ? doSomething : doSomethingElse
}
}
<Rx Java๋ฅผ ์ฌ์ฉํ ์ฐ์๋ ๋คํธ์ํฌ ํต์ >
UserAPI.getUser()
.subscribeOn(Schedulers.io())
.flatMap(user -> VerifyAPI.checkValid(user))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(isUserValid -> isUserValid ? doSomething : doSomethingElse);
- ์ฐ์ API ํธ์ถ
- ํํ API ํธ์ถ
- ํ ์คํ
- UI ๋ก์ง ํธ๋ค๋ง
- ๋น๋๊ธฐ ํต์ ์ ์์ฐจ์ ์ผ๋ก ๋ณด๋ด๊ณ ์ถ์๋ (A์์ ์ด ๋๋๊ณ B๊ฐ ์์๋์ผ๋ฉด ์ข๊ฒ ๋ค.)
- ์ฝ๋ฐฑ์ ๋ฐ์๋๋ฐ ๋ฐ๋ ํ๋ฉด์ด ์ฌ๋ผ์ ธ์ null์๋ฌ๋ฅผ ๋ฟ์ผ๋ฉด์ ์ฃฝ์ ๋
- ํธ๋ค๋ฌ๋ ์ฝ๋ฐฑ ์ง์ฅ์ ๋น ์ ธ์ ๋๋ฒ๊น ๋ ํ๋ค๊ณ ํ๊น๋ฆด ๋
- ๋๊ฐ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋ ํ์ ๊ฒฐ๊ณผ ๊ฐ์ ํฉ์ณ์ ํ๋๋ก ๋ง๋ค๊ณ ์ถ์ ๋
- ๋ฒํผ์ ์ฐํ๋ก ๋๋ฌ์ ์ด๋ฒคํธ๊ฐ ์ค๋ณต์คํ ๋ ๋
- ์ฐ๋ ๋ ๊ด๋ฆฌ๊ฐ ํ๋ค ๋
์ต์ ๋ฒ ํจํด์ ํ ๊ฐ์ฒด์ ์ํ๊ฐ ๋ฐ๋๋ฉด ๊ทธ ๊ฐ์ฒด์ ์์กดํ๋ ๋ค๋ฅธ ๊ฐ์ฒด๋ค์๊ฒ ์ฐ๋ฝ์ด ๊ฐ๊ณ ์๋์ผ๋ก ์ ๋ณด๊ฐ ๊ฐฑ์ ๋๋ 1:N ์ ๊ด๊ณ๋ฅผ ์ ์ํฉ๋๋ค.
4.1.2. Iterator pattern
4.1.3. Functional programming
(1.3. ํจ์ํ ๋ฐ์ ํ๋ก๊ทธ๋๋ฐ)
4.1.4. MVVM model
4.1.5. Dataflow programming
####4.2. ๊ธฐ๋ณธ์ ์ธ ๋น๋ฉ ๋ธ๋ก
๋ฐ์์ ์ธ ์ฝ๋์ ๊ธฐ๋ณธ์ ์ธ ๋น๋ฉ ๋ธ๋ก์ Observable๋ค๊ณผ Subscriber๋ค์ ๋๋ค. ์ฌ์ค ๊ฐ์ฅ ์์ ๋น๋ฉ ๋ธ๋ก์ Observer์ด์ง๋ง ์ค์ ๋ก Subscriber๋ฅผ ๋ ์์ฃผ ์ฌ์ฉํฉ๋๋ค.
์ฌ๊ธฐ์ Observable์ ์์ดํ ์ ๋ฐํํ๋ ๊ณณ์ ์ฌ์ฉ๋๊ณ Subscriber์ ์ด ์์ดํ ๋ค์ ์๋นํ๋๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ์คํ(์์?)ํ๋ ๋ถ๋ถ์ ๋๋ค.
Observable์ ์ํด์๋ Subcrber๋ง๋ค Subcirber.onNext( ), Subscriber.onComplete( ), ๋๋ Subscriber.onError( )๊ฐ ๋ค๋ฐ๋ฆ ๋๋ค.
Observable์ ์๊น ๋งํ๋ฏ์ด์ด๋ ์ฑ๊ณต์ ์ธ ์๋ฃ(Subscriber. onComplete( )) ๋๋ ์๋ฌ(Subscriber.onEror( ))์ ์ธํด์ ์ข ๋ฃ๊ฐ ๋๋๋ฐ ๊ทธ ๊ฐ๊ฐ์ ์ํ๊ฐ ์์ ๋ฉ์๋์ ์ํด์์ต๋๋ค.
์ค์ค๋ก ์ดํดํด๋ณธ ๋ฐ๋ก๋ ์ด ๋ถ๋ถ์ด ๋ฉ์๋ ์ฒ๋ผ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ณตํ๊ณ ์ฒ๋ฆฌํ๋ ๋ถ๋ถ์ ๋๋ค. ์ด๊ฒ ๊ฐ๋ฅํ ์ด์ ๋ ์ฐ์์ ์ผ๋ก ๋ฉ์๋๋ฅผ ๋ถ๋ฅผ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. Observable์ด๋ Subscriber์ด๋ ํท๊ฐ๋ฆด ํ์๊ฐ ์๋๊ฒ Observable ์์ Subscriber์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ธฐ ๊ฒฐ๊ณผ๋ค์ ์์ ๋ฐ๋ ๋ถ๋ถ์ด Observer์ด๋ค.
Observable์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฟผ๋ฆฌ๋ผ๊ณ ์๊ฐํ๊ณ Subscriber์ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ง๊ณ ํ๋ฉด์ ๋ณด์ฌ์ค๋ค๊ณ ์๊ฐ ํ ์ ์๋ค. ๋ ๋ค๋ฅธ ์๋ก๋ Observable์ ํ๋ฉด์ ํด๋ฆญ์ด๊ณ Subscriber์ ๊ทธ์ ๋ํ ๋ฐ์์ด๋ผ๊ณ ๋ณผ ์ ์๋ค.
- map( )
- flatMap( )
- just( )
- merge( )
- filter( )
- action( )
http://pluu.github.io/blog/rx/2015/04/29/rxjava/
Observable<String> myObservable = Observable.create(
new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> sub) {
sub.onNext(โHello, world!โ);
sub.onCompleted();
}
}
);
Observable
Subscriber<String> mySubscriber = new Subscriber<String>() {
@Override
public void onNext(String s) { System.out.println(s); }
@Override
public void onCompleted() { }
@Override
public void onError(Throwable e) { }
};
Subscriber
myObservable.subscribe(mySubscriber);
// Outputs โHello, world!โ
ํฉ์ท!!!โฅโชโฅโฉโฅโช
https://academy.realm.io/kr/posts/kau-felipe-lima-adopting-rxjava-airbnb-android/
http://alltogetherwe.tistory.com/16
https://medium.com/@LIP/rxjava-29cfb3ceb4ca