디자인 패턴은 유용하다.
람다 표현식을 디자인 패턴에 적용한다면 더 간결하게 구현할 수 있다.
옵저버 패턴
어떤 이벤트가 발생했을 때 한 주체가되는 객체가 다른 옵저버가 되는 객체에게 알림을 보내야 하는 상황에 사용된다.
예를 들어 유튜브 구독자에게 알림이 가능 상황을 예시로 들 수 있겠다.
다음 예제에서는 주식시장에서 주식 가격에 따라 자동으로 주식을 사고 파는 상황을 간단하게 구현해 보겠다.
첫째로 주체가 되는 객체를 구현하면 다음과 같다.
1
2
3
4
|
public interface Subject {
void registerObserver(Observer o);
void notifyObservers(int money);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class StockMarket implements Subject {
private final List<Observer> observers = new ArrayList<>();
@Override
public void registerObserver(final Observer o) {
this.observers.add(o);
}
@Override
public void notifyObservers(final int money) {
System.out.println("현재 주식가격은 : " + money);
observers.forEach(o -> o.notify(money));
}
}
|
그리고 주식시장을 관찰하는 옵저버객체를 구현해보자.
1
2
3
4
|
public interface Observer {
void notify(int money);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class BuyStock implements Observer {
private final int buyPoint;
public BuyStock(final int buyPoint) {
this.buyPoint = buyPoint;
}
@Override
public void notify(final int money) {
if (money < buyPoint){
System.out.println("주식을 구입했습니다");
}
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class SellStock implements Observer{
private final int sellPoint;
public SellStock(final int sellPoint) {
this.sellPoint = sellPoint;
}
@Override
public void notify(final int money) {
if (money > sellPoint){
System.out.println("주식을 팔았습니다");
}
}
}
|
위의 코드를 실행하는 방법은 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class Main {
public static void main(String[] args) {
StockMarket stockMarket = new StockMarket();
stockMarket.registerObserver(new SellStock(500));
stockMarket.registerObserver(new BuyStock(300));
stockMarket.notifyObservers(200);
stockMarket.notifyObservers(300);
stockMarket.notifyObservers(400);
stockMarket.notifyObservers(500);
stockMarket.notifyObservers(600);
//출력 결과
// 현재 주식가격은 : 200
// 주식을 구입했습니다
// 현재 주식가격은 : 300
// 현재 주식가격은 : 400
// 현재 주식가격은 : 500
// 현재 주식가격은 : 600
// 주식을 팔았습니다
}
}
|
람다 표현식 사용
위의 코드는 옵저버가 늘어날 수록 그에 해당하는 클래스를 추가 해주어야 하는 수고로움이 있다.
하지만 람다 표현식을 사용한다면 그 수고로움을 덜 수 있다.
람다 표현식을 사용하여 구현하면 다음과 같다.
먼저 주체가 되는 클래스구현까지는 동일하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public interface Subject {
void registerObserver(Observer o);
void notifyObservers(int money);
}
public class StockMarket implements Subject {
private final List<Observer> observers = new ArrayList<>();
@Override
public void registerObserver(final Observer o) {
this.observers.add(o);
}
@Override
public void notifyObservers(final int money) {
System.out.println("현재 주식가격은 : " + money);
observers.forEach(o -> o.notify(money));
}
}
|
여기서 옵저버를 명시적으로 인스턴스화 하지 않고 람다 표현식으로 직접 전달할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
public class Main {
public static void main(String[] args) {
StockMarket stockMarket = new StockMarket();
stockMarket.registerObserver((int money) -> {
if (money > 500) {
System.out.println("주식을 팔았습니다");
}
});
stockMarket.registerObserver((int money) -> {
if (money < 300) {
System.out.println("주식을 구입했습니다");
}
});
stockMarket.notifyObservers(200);
stockMarket.notifyObservers(300);
stockMarket.notifyObservers(400);
stockMarket.notifyObservers(500);
stockMarket.notifyObservers(600);
//출력 결과
// 현재 주식가격은 : 200
// 주식을 구입했습니다
// 현재 주식가격은 : 300
// 현재 주식가격은 : 400
// 현재 주식가격은 : 500
// 현재 주식가격은 : 600
// 주식을 팔았습니다
}
}
|
※ 람다 표현식을 사용하는 것이 항상 좋은 것은 아니다.
불필요한 코드를 제거할 수 있어서 람다 표현식이 유용할 수 있고, 경우에 따라 기존의 방식을 고수하는 것이 더 좋을 수 있다.
반응형
'Java' 카테고리의 다른 글
람다 표현식을 활용한 디자인패턴 - 팩토리 패턴 (0) | 2020.04.14 |
---|---|
람다 표현식을 활용한 디자인패턴 - 의무 체인 패턴 (0) | 2020.04.11 |
람다 표현식을 활용한 디자인패턴 - 템플릿 메서드 (0) | 2020.04.08 |
람다 표현식을 활용한 디자인패턴 - 전략 패턴 (0) | 2020.04.08 |
스트림 활용 정리 (0) | 2020.04.04 |