DevLog ๐ถ
[ReactiveProgramming] Iterable, Iterator์ Observer Pattern ๋ณธ๋ฌธ
Back-end/Spring
[ReactiveProgramming] Iterable, Iterator์ Observer Pattern
dolmeng2 2022. 10. 24. 13:45
- ํ ๋น์ '์คํ๋ง ๋ฆฌ์กํฐ๋ธ ํ๋ก๊ทธ๋๋ฐ' ๊ฐ์๋ฅผ ๋ฃ๊ณ ์ ๋ฆฌํ ๊ธ์ ๋๋ค.
- ์ ์ฒด ์์ค์ฝ๋) https://github.com/Cl8D/SpringReactive
โ๏ธ Iterable / Iterator
package chapter1;
import java.util.Iterator;
public class Basic {
public static void main(String[] args) {
// Iterable์ ๊ตฌํํ ๊ตฌํ์ฒด ์์ฑ
Iterable<Integer> iter = () ->
// Iterator๋ผ๋ ๋๊ตฌ๋ฅผ custom ํ๊ธฐ
new Iterator<Integer>() {
// 1~10๊น์ง ์์ฑ
int i = 0;
final static int MAX = 10;
@Override
public boolean hasNext() {
return i < MAX;
}
@Override
public Integer next() {
return ++i; // ๋ค์ ๊ฐ ๊ฐ์ ธ์ค๊ธฐ
}
};
// custom์ด์ง๋ง for-each ๊ตฌ๋ฌธ์ ์ฌ์ฉํ ์ ์๋ค๋ ๊ฒ. (enhanced for)
// ์ฆ, ์๋ฐ์์ for-each๋ Iterable์ ๊ตฌํ์ฒด์์ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
for(Integer i : iter) {
System.out.println(i);
}
// Java 10 ๋ฒ์
for(Iterator<Integer> it = iter.iterator(); it.hasNext();) {
// pull์ ๋๋, ๊ฐ์ ๊ฐ์ ธ์ค๋ ๊ฒ.
System.out.println(it.next());
}
}
}
- 1~10๊น์ง ์์ฑํ๋ Iterator ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ.
- ์ด๋ hatNext()์ next()๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํด์ ์ฌ์ ์ํ ์ ์๋ค.
- hasNext()๋ ๋ค์ ์์๊ฐ ์๋์ง, next()๋ ๋ค์ ์์๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ.
- for-each ๊ตฌ๋ฌธ์ ์ด๋ ๊ฒ ์ปค์คํ
ํ ๊ฐ์ฒด์๋ ์ฌ์ฉํ ์ ์๋ค.
- ์ฆ, Iterable์ ๊ตฌํ์ฒด๋ผ๋ฉด enhanced for๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ด๋ค.
โ๏ธ Observer
- Full Code
package chapter1;
import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@SuppressWarnings("deprecation")
public class ObserverTest {
/**
* 1. ์ต์ ๋ฒ ํจํด์๊ฒ๋ complete๊ฐ ์๋ค.
* 2. ์ฝ๋๊ฐ ๋์ํ๋ค ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค๋ฉด ์์ธ ์ ํ ๋ฐฉ์, ์์ธ ์ฒ๋ฆฌ ๋ฐฉ์์ ๋ํด ์ด๋ ค์์ง๋ค.
*/
public static void main(String[] args) {
// iterable ๋๋ฌธ์ deprecate๋ ์น๊ตฌ...
Observer observer1 = new Observer() {
// ์ผ์ข
์ subscriber
// notifyObservers ๋์ ์ ์คํ๋๋ค.
// ์ฆ, observable์ด ๋์ง ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ ์ถ๋ ฅํด์ฃผ๋ ์ญํ !
@Override
public void update(Observable o, Object arg) {
System.out.println("observer1 = " + arg);
}
};
Observer observer2 = new Observer() {
@Override
public void update(Observable o, Object arg) {
System.out.println("observer2 = " + arg);
}
};
Observer observer3 = new Observer() {
@Override
public void update(Observable o, Object arg) {
System.out.println("observer3 = " + arg);
}
};
IntObservable io = new IntObservable();
// observer๋ฅผ ๋ฑ๋กํด์ค๋ค. ์ด๋ฌ๋ฉด observable์ด ๋์ง ์์
์ ๋ฑ๋ก๋ ์ต์ ๋ฒ๋ค์ด ๋ฐ๋๋ค.
// ์คํ ์์์ ๊ฒฝ์ฐ ๊ฐ์ฅ ๋ง์ง๋ง์ ๋ฑ๋กํด์ค ์ต์ ๋ฒ๋ถํฐ ์์ฐจ์ ์ผ๋ก ์คํ๋๋ ๊ฒ ๊ฐ๋ค.
io.addObserver(observer1);
io.addObserver(observer2);
io.addObserver(observer3);
// Executors๋ฅผ ํตํด์ ExecutorService ์์ฑ ๊ฐ๋ฅ
// ์ค๋ ๋๋ฅผ ์๋กญ๊ฒ ์์ฑํด์ค ๋ค์์ ํ ๋นํด์ฃผ๊ธฐ
ExecutorService es = Executors.newSingleThreadExecutor();
es.execute(io);
// execute๋ณด๋ค ๋์ค์ ์
๋ ฅํ๋๋ฐ๋ ๋ ๋จผ์ ์คํ๋๋ค.
// excute๋ ์ค๋ ๋๋ฅผ ์๋กญ๊ฒ ์์ฑํด์ (๋ณ๊ฐ์ ์ค๋ ๋) ๋์ํ๊ธฐ ๋๋ฌธ์ ๋ ๋์ค์ ๋์ํ๊ฒ ๋๋ ๊ฒ
System.out.println("Hello!");
es.shutdown();
}
// observable์ ์ธ๋ถ์์ ์ด๋ฒคํธ๋ฅผ ๋ง๋ค์ด๋ด์ผ ํ๋ค.
// ๋น๋๊ธฐ๋ก ์คํํ๊ธฐ ์ํด์ runnable ๊ตฌํ
static class IntObservable extends Observable implements Runnable {
@Override
public void run() {
for(int i=1; i<=10; i++) {
setChanged(); // ๋ณํ๊ฐ ์๊ฒผ์์ ์๋ ค์ฃผ๊ธฐ ์ํด์, Observable์ ๋ฑ๋ก๋์ด ์์.
// ์ผ์ข
์ Push ๋๋. ์ฌ์ค iter์์์ it.next()์ ๋น์ทํ ๋๋์ด๋ค.
notifyObservers(i); // ์ต์ ๋ฒ์๊ฒ ์๋ ค์ฃผ๊ธฐ!, ์ผ์ข
์ publisher
}
}
}
}
- ์ต์ ๋ฒ ํจํด
- complete()๊ฐ ์๋ค.
- ์ฝ๋๊ฐ ๋์ํ๋ค ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์์ธ๊ฐ ์ ํ๋๋ฉฐ, ์ด ๊ฒฝ์ฐ ์์ธ ์ฒ๋ฆฌ์ ๋ํด ๊น๋ค๋ก์์ง๋ค.
- Observer ๊ฐ์ฒด
- ์ผ์ข ์ subscriber๋ก์, notifyObservers๊ฐ ๋์ํ๋ฉด ์คํ๋๋ค.
- ์ฆ, observable์ด ๋์ง ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ ์ถ๋ ฅํด์ฃผ๋ ์ญํ ์ ํ๋ค.
Observer observer1 = new Observer() {
@Override
public void update(Observable o, Object arg) {
System.out.println("observer1 = " + arg);
}
};
Observer observer2 = new Observer() {
@Override
public void update(Observable o, Object arg) {
System.out.println("observer2 = " + arg);
}
};
Observer observer3 = new Observer() {
@Override
public void update(Observable o, Object arg) {
System.out.println("observer3 = " + arg);
}
};
- IntObservable
- IntObservable์ ์ต์ ๋ฒ๋ฅผ ๋ฑ๋กํด์ฃผ๋ ๊ฑธ ๋ณผ ์ ์๋๋ฐ, observable์ด ๋์ง ์์ ์ ๋ฑ๋ก๋ ์ต์ ๋ฒ๋ค์ด ๋ฐ๊ฒ ๋๋ค.
- ์คํ์ ๊ฐ์ฅ ๋ง์ง๋ง์ผ๋ก ๋ฑ๋กํ ์ต์ ๋ฒ๋ถํฐ ์ญ์ผ๋ก ์ํ๋๋ค.
- observer3 = 1
- observer2 = 1
- observer1 = 1
- observer3 = 2
- observer2 = 2
- observer1 = 2 ...
IntObservable io = new IntObservable();
io.addObserver(observer1);
io.addObserver(observer2);
io.addObserver(observer3);
- ๋ค๋ฅธ ์ค๋ ๋์์ ์คํ๋๋๋ก ์์ฑ
- main ์ค๋ ๋๊ฐ ์๋ ๋ณ๊ฐ์ ์ค๋ ๋์์ ์คํํ์๊ธฐ ๋๋ฌธ์ Hello! ์คํ ๋ค์ ์์ฐจ์ ์ผ๋ก ๊ฒฐ๊ณผ๊ฐ์ด ์ถ๋ ฅ๋๋ค.
ExecutorService es = Executors.newSingleThreadExecutor();
es.execute(io);
System.out.println("Hello!");
es.shutdown();
- ์ธ๋ถ์์ ์ด๋ฒคํธ ์์ฑํด์ฃผ๊ธฐ
- Runnable ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๊ฒ์ ๋ณผ ์ ์๋๋ฐ, ์ด๋ ๋น๋๊ธฐ๋ก ์คํํ๊ธฐ ์ํจ์ด๋ค.
- Observable์ setchanged() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด Observable ๊ฐ์ฒด์ ๋ณํ๊ฐ ์๊ฒผ์์ ๋ํ๋ด๋ฉฐ ๋ด๋ถ์ ์ผ๋ก changed ๋ณ์๊ฐ true๋ก ์ธํ ๋๋ค.
- notifyObservers() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์ผ์ข ์ publisher๋ก์, ๋ฑ๋ก๋ Observer๋ค์๊ฒ ๋ณํ๋ ๋ด์ฉ์ ์ ๋ฐ์ดํธํด์ค๋ค.
static class IntObservable extends Observable implements Runnable {
@Override
public void run() {
for(int i=1; i<=10; i++) {
setChanged(); // ๋ณํ๊ฐ ์๊ฒผ์์ ์๋ ค์ฃผ๊ธฐ ์ํด์, Observable์ ๋ฑ๋ก๋์ด ์์.
// ์ผ์ข
์ Push ๋๋. ์ฌ์ค iter์์์ it.next()์ ๋น์ทํ ๋๋์ด๋ค.
notifyObservers(i); // ์ต์ ๋ฒ์๊ฒ ์๋ ค์ฃผ๊ธฐ!, ์ผ์ข
์ publisher
}
}
}
'Back-end > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Comments