정의
옵저버 패턴은 주체가 어떤 객체의 상태 변화를 관찰하다가 상태 변화가 있을 때 마다 메서드 등을 통해 옵저버 목록에 있는 옵저버에게 변화를 알려주는 패턴이다.
- 객체와 주체가 분리되어 있을 수도 있고, 객체와 주체가 합쳐진 옵저버 패턴이 있을 수도 있다.
여기서 주체란, 객체의 상태 변화를 보고있는 관찰자이며, 옵저버들이란 이 객체의 상태 변화에 전달되는 메서드등을 기반으로 추가적인 변화 사항들이 생기는 객체들을 의미한다. - 옵저버 패턴은 주로 이벤트 기반 시스템에 사용하며, MVC 패턴에도 많이 사용된다. 예를 들어, 모델에서 변경사항이 생겨 update() 메서드로 옵저버인 뷰에 알려주고 이를 기반으로 컨트롤러 등이 작동하는 방식이다.
옵저버 패턴의 장점
- 주체와 관찰자들 사이의 결합도를 낮출 수 있다. 주체와 관찰자들은 서로 독립적으로 존재할 수 있으며, 주체의 변경이 있어도 관찰자들은 그에 대해서 더이상 알 필요가 없다.
- 주체와 관찰자들 사이의 일관성을 유지할 수 있다.
- 새로운 관찰자를 추가하기가 쉽다.
옵저버 패턴의 단점
- 많은 관찰자들이 존재할 경우, 주체에서 관찰자들을 일괄적으로 알릴 때 성능 이슈가 발생할 수도 있다.
- 관찰자들이 동일한 이벤트를 처리해야 할 경우, 관찰자들의 처리 순서가 중요한 경우도 있을 수 있다.
옵저버 패턴 예시 자바코드
해당 자바코드를 통해 옵저버 패턴이 어떻게 쓰이는지 알아보자.
먼저, 주체와 관찰자의 인터페이스를 정의해준다.
// Subject(주체) 인터페이스
public interface Subject {
void registerObserver(Observer o); // 관찰자 등록
void removeObserver(Observer o); // 관찰자 제거
void notifyObservers(); // 관찰자들에게 알림
}
// Observer(관찰자) 인터페이스
public interface Observer {
void update(int data); // 주체로부터 상태 변경 알림을 받음
}
구체적인 주체 클래스를 정의한다. 여기서, 데이터를 변경하면 해당 주체에 속한 옵저버들에게 상태가 변했다는 것을 notifyObservers() 메서드를 통해서 알려준다.
// 구체적인 주체 클래스
class Topic implements Subject {
private List<Observer> observers;
private int data;
public ConcreteSubject(){
observers = new ArrayList<>();
}
public void registerObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o){
observers.remove(o);
}
public void notifyObservers(){
this.observers.forEach(Observer::update);
}
public void setData(int data){
this.data = data;
notifyObservers(); // 상태 변경 후 관찰자들에게 알림
}
}
구체적인 관찰자 클래스를 정의한다.
주체에서 데이터를 변경해서 각 옵저버들에게 상태를 변화시키면 update 메서드가 호출된다.
// 구체적인 관찰자 클래스
class TopicSubscriber implements Observer {
private int data;
public void update(int data) {
this.data = data;
System.out.println("관찰자가 업데이트 되었습니다. " + data);
}
}
// 사용 예시
public class Main {
public static void main(String args[]){
Topic subject = new Topic();
TopicSubscriber observer1 = new TopicSubscriber();
TopicSubscriber observer2 = new TopicSubscriber();
subject.registerObserver(observer1);
subject.registerObserver(observer2);
subject.setData(1); // Observer update 1
subject.removeObserver(observer1);
subject.setData(2); // Observer update 2
}
}
'Computer Science > Design Pattern' 카테고리의 다른 글
[디자인 패턴] 전략(Strategy) 패턴 (0) | 2023.03.15 |
---|---|
[디자인 패턴] Factory 패턴 (0) | 2023.03.14 |
[디자인 패턴] Singleton 패턴 (0) | 2023.03.13 |