각각의 파생 옵서버는 notify
함수를 구현함으로써 이벤트가 발생했을 때 처리할 각자의 동작을 정의해야 한다.
주체에는 일반적으로 등록(register), 제거(unregister) 메서드가 있는데, 전자는 새로운 옵저버를 목록에 등록하고 후자는 목록에서 옵저버를 뺀다.
옵저버 패턴을 구현한 예시를 보자.
public interface Observer {
public void update(String title, String news);
}
위 인터페이스는 모든 옵저버들이 상속하는 인터페이스이다.
update라는 메서드를 오버라이드해야한다.
그래야 subject에서 state가 변경되었을때 옵저버에게 알려주기위해 update메서드를 호출해야하기때문이다.
public interface Publisher {
public void add(Observer observer);
public void delete(Observer observer);
public void notifyObserver();
}
위 인터페이스는 subject의 인터페이스이다.
add, delete메서드는 observer들을 등록/제거하기위해서 사용되고,
notifyObserver메서드는 프로퍼티 변경 시 옵저버들에게 알려주기위한 메서드이다.
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;
}
}
옵저버들을 관리하는 observers라는 배열을 가지고,
subject의 값이 변경될때 setNewsInfo라는 메서드를 호출해서 notifyObserver를 실행시킨다.
그래서 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);
}
}
실제 observer클래스를 보면 update메서드를 오버라이드한것을 볼수있다.
subject가 실제로 호출하는 메서드이다.
public class MainClass {
public static void main(String[] args) {
NewsMachine newsMachine = new NewsMachine();
AnnualSubscriber as = new AnnualSubscriber(newsMachine);
newsMachine.setNewsInfo("오늘 한파", "전국 영하 18도 입니다.");
}
}