읭읭...
옵저버 패턴
옵저버란 영어로 직역하면 관찰자라는 뜻이 있는데, 이러한 뜻처럼 어느 대상을 관찰하고 있다고 생각하면 된다. 그럼 관찰자가 보고 있는 대상에게 특이사항이 발견되면? 그럼 관찰자는 다른 누군가에게 그 상황을 알릴 것이다.
디자인 패턴 중 옵저버 패턴 역시 비슷한 역할을 한다.
관찰하고 있는 대상자의 상태가 변화가 있을 때마다 대상자는 직접 목록의 각 관찰자들에게 알리고, 관찰자들은 알림을 받아 조치를 위하는 행동 패턴이다.
또한 옵저버 패턴은 다른 패턴들과 다르게 One-To-Many 즉, 일대다 의존성을 갖는다. 왜냐하면 분산 이벤트 핸들링을 주로 구현하는 데에 사용되기 때문이며, Pub/Sub 모델로도 알려져 있다.
프로그램에서 옵저버 패턴은
관찰
보단 갱신을 위한 정보를전달
받기를 기다린다고 보는 것이 정확하다.
그래서 능동적인 느낌보단 수동적인 느낌으로 생각하면 이해하기 편하다.
크게 관찰 대상자와 관찰자로 나눠 볼 수 있다.
각 인터페이스와 구현체들에 대한 설명이다.
Interface
>>Observers()
: Observer들을 리스트(List, Map 등)로 모아서 관리하고 있다.registerObserver()
& removeObserver()
: Subject의 역할은 관찰자인 Observer들을 내부 리스트에 등록/삭제 하는 메서드를 갖고 있다. (register, remove)notifyObservers()
: Subject가 상태를 변경하거나 어떤 동작을 실행할 때, Observer들에게 이벤트 알림을 발행한다.Interface
>>update()
: Subject의 상태 업데이트에 대해 전후 정보를 처리한다.옵저버 패턴의 핵심은 옵저버들을 리스트로 관리하고 리스트에 있는 옵저버 객체들에게 모두 메서드 위임을 통하여 전파 행위를 한다는 점이다.
notifyObserver()
를 통해 옵저버한테 통보한다.update()
를 통해 값을 수정하거나 삭제하는 등 적절한 대응을 할 수 있다.interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObserver();
}
class ConcreteSubject implements Subject {
// 관찰자들을 등록하여 담는 리스트
List<IObserver> observers = new ArrayList<>();
// 관찰자를 리스트에 등록
@Override
public void registerObserver(Observer o) {
observers.add(o);
System.out.println(o + " 구독 완료");
}
// 관찰자를 리스트에 제거
@Override
public void removeObserver(Observer o) {
observers.remove(o);
System.out.println(o + " 구독 취소");
}
// 관찰자에게 이벤트 송신
@Override
public void notifyObserver() {
for(Observer o : observers) { // 관찰자 리스트를 순회하며
o.update(); // 위임
}
}
}
interface Observer {
void update();
}
class ObserverA implements Observer {
public void update() {
System.out.println("ObserverA 한테 이벤트 알림이 왔습니다.");
}
public String toString() { return "ObserverA"; }
}
class ObserverB implements Observer {
public void update() {
System.out.println("ObserverB 한테 이벤트 알림이 왔습니다.");
}
public String toString() { return "ObserverB"; }
}
public class Client {
public static void main(String[] args) {
// 발행자 등록
Subject publisher = new ConcreteSubject();
// 발행자를 구독할 관찰자들 리스트로 등록
Observer observer1 = new ObserverA();
Observer observer2 = new ObserverB();
publisher.registerObserver(observer1);
publisher.registerObserver(observer2);
// 관찰자에게 이벤트 전파
publisher.notifyObserver();
// ObserverB가 구독 취소
publisher.removeObserver(observer2);
// ObserverA 한테만 이벤트 전파
publisher.notifyObserver();
}
}
# 결과 화면
ObserverA 구독 완료
ObserverB 구독 완료
ObserverA 한테 이벤트 알림이 왔습니다.
ObserverB 한테 이벤트 알림이 왔습니다.
ObserverB 구독 취소
ObserverA 한테 이벤트 알림이 왔습니다.
https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-%EC%98%B5%EC%A0%80%EB%B2%84Observer-%ED%8C%A8%ED%84%B4-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EC%9E%90
https://yongj.in/design%20pattern/observer-pattern/