Observer
Observer Pattern
What’s Observer Pattern ?
-
종속자(Dependent), 게시 - 구독(Publish - Subscribe) 이라고도 불림
- 객체 사이에 일 대 다의 의존 관계를 정의해 두어, 어떤 객체의 상태가 변할 때 그객체에 의존성을 가진 다른객체들이 그 변화를 통지받고 자동으로 갱신 될 수 있게 만듭니다.
- 주체는 독립된 여러 개의 감시가 있을 수 있습니다. 모든 감시자는 주체의 상태 변화가 있을 때마다 이 변하를 통보받습니다. 각 감시자는 주체의 상태와 자신의 상태를 동기화 시키기 위해 주체의 상태를 알아봅니다.
Purpose
-
용도
- 한 객채에 가해진 변경으로 다른객체를 변경해야 하고, 프로그래머들은 얼마나 많은 객체들이 변경되어야 하는지 몰라도 될때
-
어떤 객체가 다른 객체에 자신의 변화를 통보할 수 있는데, 그변화에 관심있어 하는 객체들이 누구인지에 대한 가정 없이도 그러한 통보가 될때
뉴스 - 구독자 옵저버 패턴 뉴스머신 Subject 구독자 Observer 뉴스머신이 상태를 알리는 행위 notifyObserver() 구독자가 상태를 갱신하는 행위 update()
UML
옵저버 패턴의 기본 UML 다이어그램
옵저버 패턴으로 설계한 구독(Publish - Subscribe) UML 다이어그램
Example
// 1. Observer 인터페이스 정의하기
// 정기구독자 및 이벤트 구독자가 아래의 인터페이스를 구현한다.
public interface Observer {
public void update(String title, String news);
}
// 2. Publisher 인터페이스 정의
// 뉴스머신이 아래의 인터페이스를 구현한다.
public interface Publisher {
public void add(Observer observer);
public void delete(Observer observer);
public void notifyObserver();
}
// 3. Publisher 인터페이스를 구현하는 NewsMachine 클래스 정의
public class NewsMachine implements Publisher {
private ArrayList<Observer> observers;
private String title;
private String news;
public NewsMachine() {
observers = new ArrayList<>();
}
@Override
public void add(Observer observer) { // 새로운 구독자를 추가하는 메소드
observers.add(observer);
}
@Override
public void delete(Observer observer) { // 구독자를 삭제하는 메소드
int index = observers.indexOf(observer);
observers.remove(index);
}
@Override
public void notifyObserver() { // 구독자들에게 뉴스를 통보하는 메소드
for(Observer observer : observers) {
observer.update(title, news);
}
}
public void setNewsInfo(String title, String news) { // 뉴스를 저장하는 메소드
this.title = title;
this.news = news;
notifyObserver();
}
public String getTitle() {
return title;
}
public String getNews() {
return news;
}
}
// 4. AnnualSubscriber 클래스 정의
// Observer 인터페이스를 상속하여 만든 매년구독자 클래스입니다. Publisher 인터페이스를 구현한 클래스에서 Observer 인터페이스의 update()메소드를 호출 하게되면 자신이 구현한 메소드를 호출합니다.
public class AnnualSubscriber implements Observer {
private String newsString;
private Publisher publisher;
public AnnualSubscriber(Publisher publisher) {
this.publisher = publisher;
publisher.add(this);
}
@Override
public void update(String title, String news) {
this.newsString = title + " \n -------- \n " + news; display();
}
private void display() {
System.out.println("\n\n오늘의 뉴스\n============================\n\n" + newsString);
}
}
// 5. EventSubscriber 클래스 정의
// Observer 인터페이스를 상속하여 만든 이벤트구독자 클래스입니다. Publisher 인터페이스를 구현한 클래스에서 Observer 인터페이스의 update()메소드를 호출 하게되면 자신이 구현한 메소드를 호출합니다.
public class EventSubscriber implements Observer {
private String newsString;
private Publisher publisher;
public EventSubscriber(Publisher publisher) {
this.publisher = publisher;
publisher.add(this);
}
@Override public void update(String title, String news) {
newsString = title + "\n------------------------------------\n" + news;
display();
}
public void display() {
System.out.println("\n\n=== 이벤트 유저 ===");
System.out.println("\n\n" + newsString);
}
}
public class MainClass {
public static void main(String[] args) {
NewsMachine newsMachine = new NewsMachine();
AnnualSubscriber as = new AnnualSubscriber(newsMachine);
EventSubscriber es = new EventSubscriber(newsMachine);
newsMachine.setNewsInfo("오늘 한파", "전국 영하 18도 입니다.");
newsMachine.setNewsInfo("벛꽃 축제합니다", "다같이 벚꽃보러~");
}
}