4. 옵저버 패턴 (Observer Pattern)
재미있다~ 22
본 게시글은 책 : 면접을 위한 CS 전공지식 노트 (출판사 : 길벗, 주홍철 지음) 을 참조하여 작성하였습니다. + 구글링
♣ 옵저버 패턴 ( Observer Pattern )?
- 어떤 객체의 상태가 변할 때 그와 연관된 객체들에게 변화를 알려주는 디자인 패턴
책의 내용에 따르면, 주체가 어떤 객체의 상태 변화를 관찰하다가 상태 변화가 있을 때마다 메서드 등을 통해 옵저버 목록에 있는 옵저버들에게 변화를 알려주는 디자인 패턴이라고 적혀있습니다.
여기서의 주체란 객체의 상태 변화를 보고 있는 관찰자이며, 옵저버들이란 이 객체의 상태 변화에 따라 전달되는 메서드 등을 기반으로 '추가 변화 사항' 이 생기는 객체들을 의미합니다.
또한 주체와 객체를 따로 두지 않고 상태가 변경되는 객체를 기반으로 구축하기도 합니다. (아래의 예시)
◈ 요약하면 주체 변화 발생시 옵저버들에게 변화를 알려줍니다.
♣ 옵저버 패턴 예시
- 가정 1 :트위터 계정 F, A, B, C, D 가 존재
- 가정 2: 트위터 계정 A,B,C,D는 F를 팔로우.
위의 상황을 가정 했을 때, F 객체에서 어떠한 정보 변경이 발생 시, 변화 알림이 A,B,C,D 옵저버들에게 발생합니다.
또한 후에 포스팅 할 MVC 패턴도 옵저버 패턴이 사용됩니다.
( 모델(Model)에 변경사항이 생기면 뷰(View)에 알려주고, 이를 기반으로 컨트롤러(Controller)등이 작동)
♣ 예시 코드
package design04_ObserverPattern;
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 ObserverPatternTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 주체이자 객체
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("you are not alone.");
}
}
▷ 코드 내 핵심 사항 (동적으로 코드 수정이 아닌 클래스 추가를 통하여 전략 수정 )
1. Topic 을 주체로 설계하여 옵저버들을 저장할 수 있는 observers List를 멤버로 구현.
2. 변화 발생시 notifyObservers() 멤버 함수를 통해 옵저버들에게 변화를 전달
3. a,b,c 객체들은 topic을 주체로 하는 옵저버로 설정 후 등록
4. PostMessage 를 통해 모든 옵저버들의 notify 함수를 호출, 결과적으로 옵저버들에게 topic의 변화를 알림.
공부하다보니 재밌네요~~
위의 글과 관련하여 추가적인 내용이나 피드백은 언제나 환영입니다 :)