옵저버 패턴이란?
- 객체의 상태 변화가 다른 객체들에게 자동으로 통지되는 패턴
구성요소
Subject(주체)
: 상태가 변경될 때 알림을 보내는 주체, 옵저버 객체들을 등록, 삭제하고 상태가 변경될 때 옵저버들에게 알림을 보냄Observer(옵저버)
: 주체의 상태 변화를 관찰하고 이에 반응하는 객체, 이들은 주체에 등록되어 있으며 주체로부터 알림을 받음
장점
느슨한 결합
: 주체와 옵저버는 독립적으로 존재하고, 상호 작용 시 서로 대한 정보가 필요하지 않다.확장성
: 새로운 옵저버를 쉽게 추가하거나 제거하여 시스템을 확장할 수 있다.
단점
복잡성
: 옵저버 패턴을 자주 구성하면 구조와 동작을 알아보기 힘들어져 코드 복잡도가 증가한다.성능 저하 가능성
: 다수의 옵저버 객체를 등록 이후 관리를 하지 않는다면 메모리 누수가 발생할 수도 있다.
구현 예제
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package exam;
import java.util.ArrayList;
import java.util.List;
interface Subject {
void register(Observer obj);
void unregister(Observer obj);
void notifyObservers();
Object getUpdate(Observer obj);
}
interface Observer {
void update(Subject subject);
}
class Instagram implements Subject {
private final List<Observer> observers;
private String message;
public Instagram() {
this.observers = new ArrayList<>();
this.message = "";
}
@Override
public void register(Observer obj) {
if (!observers.contains(obj)) {
observers.add(obj);
}
}
@Override
public void unregister(Observer obj) {
observers.remove(obj);
}
@Override
public void notifyObservers() {
for (Observer observer : this.observers) {
observer.update(this);
}
}
@Override
public Object getUpdate(Observer obj) {
return this.message;
}
public void postMessage(String msg) {
System.out.println("새로운 게시글을 등록했습니다 : " + msg);
this.message = msg;
notifyObservers();
}
}
class Follower implements Observer {
private String name;
public Follower(String name) {
this.name = name;
}
@Override
public void update(Subject subject) {
String msg = (String) subject.getUpdate(this);
System.out.println(name + ":: 새 게시물 알림 : " + msg);
}
}
public class Main {
public static void main(String[] args) {
Instagram instagram = new Instagram();
instagram.register(new Follower("user1"));
instagram.register(new Follower("user2"));
instagram.register(new Follower("user3"));
instagram.postMessage("오늘의 일기");
}
}
마치며
- 옵저버 패턴을 사용하면 주체와 옵저버간의 느슨한 결합을 유지할 수 있다.
- 옵저버 패턴은 DIP(의존성 역전 원칙)을 따르며, 주체가 옵저버에 의존하는 것이 아니라 추상화된 옵저버에 의존한다.
- 높은 추상화 수준을 유지하면서 객체지향적인 설계를 도와준다.