[디자인 패턴][행동 패턴] 감시자 패턴(Observer Pattern)
Updated:
1. 개요
어떤 객체의 상태가 변할 때 그 객체에 의존성을 가진 객체들에게 통지해주는 패턴
감시자 패턴(Observer Pattern)은 행동 패턴(Behavioral Pattern)의 한 종류로, 어떤 객체의 상태가 변할 때 그 객체에 의존성을 가진 다른 객체들이 그 변화를 통지받고 자동으로 갱신될 수 있게 하는 패턴이다.
2. 행동 패턴(Behavioral Pattern)
2-1. 행동 패턴이란?
행동 패턴이란 처리의 책임을 어떤 객체에게 할당하는 것이 좋은지, 알고리즘을 어떤 객체에 정의하는 것이 좋은지 등의 책임 분배와 관련된 패턴이다.
2-2. 행동 패턴 종류
3. 구성
[출처 : GoF의 디자인 패턴]
-
Subject : 감시자 객체를 추가하거나 빼는 기능을 정의한 인터페이스
-
Observer : Subject의 변화에 따른 갱신에 필요한 기능을 정의한 인터페이스
-
ConcreteSubject : Subject 인터페이스 구현체
-
ConcreteObserver : Observer 인터페이스 구현체
4. 예제 코드
엑셀에서 같은 데이터에 대해 막대 그래프, 원형 그래프, 꺾은선 그래프로 표현되어 있는 경우, 데이터가 바뀌면 세 그래프 모두 갱신되어야 한다. Observer Pattern을 이용하여 데이터가 갱신되었을 때 그래프의 값을 모두 갱신시키는 과정을 코드로 구현해보자.
4-1. Subject
[Subject.java]
1
2
3
4
5
6
7
public interface Subject {
int getState();
void setState(int state);
void attach(Observer observer);
void notifyAllObservers();
}
4-2. ConcreteSubject
[ConcreteSubject.java]
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
public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private int state;
@Override
public int getState() {
return state;
}
@Override
public void setState(int state) {
this.state = state;
notifyAllObservers();
}
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void notifyAllObservers() {
for(Observer observer : observers) {
observer.update();
}
}
}
4-3. Observer
[Observer.java]
1
2
3
4
public interface Observer {
void update();
}
4-4. ConcreteObserver
[BarGraphObserver.java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class BarGraphObserver implements Observer {
private Subject subject;
public BarGraphObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("Bar Graph State : " + subject.getState());
}
}
[PieGraphObserver.java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class PieGraphObserver implements Observer {
private Subject subject;
public PieGraphObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("Pie Graph State : " + subject.getState());
}
}
[LineGraphObserver.java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class LineGraphObserver implements Observer {
private Subject subject;
public LineGraphObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("Line Graph State : " + subject.getState());
}
}
5. 테스트
[Clinet.java]
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Client {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
new BarGraphObserver(subject);
new PieGraphObserver(subject);
new LineGraphObserver(subject);
subject.setState(10);
System.out.println("-----------------------");
subject.setState(15);
}
}
[실행 결과]
6. 특징
-
낮은 결합도 : 인터페이스에 의존하므로 낮은 결합도를 가짐
-
실시간 전파 : 한 객체의 변경사항을 실시간으로 다른 객체에 전파 가능
-
예측하지 못한 갱신 : 무엇이 변했는지 따로 관리하지 않으면, 변경의 유추가 어려움
Leave a comment