옵저버 패턴(Observer Pattern)은 객체지향 프로그래밍에서 하나의 객체 상태가 변화할 때, 그 객체에 의존하는 다른 객체들에게 자동으로 통지되어 업데이트될 수 있도록 하는 디자인 패턴이다. 주로 이벤트 핸들링 시스템에서 사용되며, 한 객체의 상태 변화에 따라 다른 객체들이 연동되도록 하는 데 유용하다.
옵저버 패턴은 주체(Subject)와 옵저버(Observer)라는 두 가지 주요 구성 요소로 이루어져 있다.
1.
주체(Subject)
•
상태 변화를 감지하는 객체이다.
•
옵저버를 등록하고 삭제하는 메서드를 제공한다.
•
상태가 변경되면 모든 등록된 옵저버에게 알림을 보낸다.
2.
옵저버(Observer)
•
주체의 상태 변화를 감지하고 이에 대응하는 객체이다.
•
주체로부터 상태 변경 알림을 받는 메서드를 제공한다.
•
클래스 다이어그램
Subject
+-----------------+
| + attach(obs) |
| + detach(obs) |
| + notify() |
+-----------------+
|
|
ConcreteSubject
+-----------------+
| - state |
| + getState() |
| + setState(state)|
+-----------------+
|
|
Observer
+-----------------+
| + update() |
+-----------------+
|
|
ConcreteObserver
+-----------------+
| - subject |
| + update() |
+-----------------+
Scss
복사
•
구현
import java.util.ArrayList;
import java.util.List;
interface Subject {
public void register(Observer obj);
public void unregister(Observer obj);
public void notifyObservers();
public Object getUpdate(Observer obj);
}
interface Observer {
public void update();
}
class Topic implements Subject {
private List<Observer> observers;
private String message;
public Topic() {
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() {
this.observers.forEach(Observer::update);
}
@Override
public Object getUpdate(Observer obj) {
return this.message;
}
public void postMessage(String msg) {
System.out.println("Message sended to Topic: " + msg);
this.message = msg;
notifyObservers();
}
}
class TopicSubscriber implements Observer {
private String name;
private Subject topic;
public TopicSubscriber(String name, Subject topic) {
this.name = name;
this.topic = topic;
}
@Override
public void update() {
String msg = (String) topic.getUpdate(this);
System.out.println(name + ":: got message >> " + msg);
}
}
public class HelloWorld {
public static void main(String[] args) {
Topic topic = new Topic();
Observer a = new TopicSubscriber("a", topic);
Observer b = new TopicSubscriber("b", topic);
Observer c = new TopicSubscriber("c", topic);
topic.register(a);
topic.register(b);
topic.register(c);
topic.postMessage("amumu is op champion!!");
}
}
Java
복사
•
결과
> Task :HelloWorld.main()
Message sended to Topic: amumu is op champion!!
a:: got message >> amumu is op champion!!
b:: got message >> amumu is op champion!!
c:: got message >> amumu is op champion!!
Shell
복사
•
코드 설명
1.
주제 인터페이스로 옵저버를 등록 및 제거하고, 상태 변화를 통지하며, 옵저버에게 최신 정보를 제공하는 메서드를 정의한다.
2.
옵저버 인터페이스로, 주제의 상태 변화를 통지받았을 때 동작할 메서드를 정의한다.
update(): 주제로부터 상태 변화 통지를 받을 때 호출
3.
Topic 클래스는 Subject 인터페이스를 구현하며, 주제 역할을 한다.
4.
TopicSubscriber 클래스는 Observer 인터페이스를 구현하며, 옵저버 역할을 한다.
5.
main 메서드에서는 Topic 객체를 생성하고, TopicSubscriber 객체 세 개를 생성하여 주제에 등록한다. topic.postMessage("amumu is op champion!!") 메서드를 호출하여 새로운 메시지를 설정하고, 등록된 모든 옵저버들에게 통지한다.
•
정리
옵저버 패턴은, 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들에게 연락이 가고, 자동으로 정보가 갱신되는 1:N 관계(혹은 1대1)를 정의한다.
인터페이스를 통해 연결하여 느슨한 결합성을 유지하며, Publisher와 Observer 인터페이스를 적용한다.
안드로이드 개발시, OnClickListener와 같은 것들이 옵저버 패턴이 적용된 것 (버튼(Publisher)을 클릭했을 때 상태 변화를 옵저버인 OnClickListener로 알려주로독 함)