Skip to content

옵서버 패턴은 객체의 상태 변화를 관찰하는 관찰자들을 생성하여, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 통지하도록 하는 패턴이다. 옵저버 패턴을 활용하면 다른 객체의 상태 변화를 별도의 함수 호출 없이 즉각적으로 알 수 있기 때문에, 이벤트를 자주 처리해야하는 프로그램에서 적합하다.


예시 코드

public interface Publisher<V> {
void add(Observer<V> observer);
void delete(Observer<V> observer);
void notifyObserver(V message);
}
public class NewsPublisher implements Publisher<String>{
private final ArrayList<Observer<String>> observers = new ArrayList<>();
@Override
public void add(Observer<String> observer) {
observers.add( observer);
}
@Override
public void delete(Observer<String> observer) {
observers.remove(observer);
}
@Override
public void notifyObserver(String message) {
for(Observer<String> observer : observers) {
observer.update(message);
}
}
}

뉴스를 생성하는 NewsPublisher 클래스를 만들었다. 위의 사진에서의 Subject에 해당한다.

Publisher는 구독중인 감시자(observer)들의 리스트를 저장해놓고, 메세지가 변경된 경우 notifyObserver()로 메세지를 observer들에게 알린다.

Publisher 인터페이스가 String이 아닌 다른 클래스의 데이터를 전송하는 경우에도 사용될 수 있도록 하기 위해 제네릭을 사용했다.


public interface Observer<V> {
void update(V content);
}
public class NewsObserver implements Observer<String> {
private Publisher<String> publisher;
public NewsObserver(Publisher<String> publisher) {
this.publisher = publisher;
publisher.add(this);
}
@Override
public void update(String message) {
display(message);
}
public void withdraw() {
publisher.delete(this);
}
public void display(String message) {
System.out.println("뉴스");
System.out.println("->" + message);
}
}

Observer를 상속받은 NewsObserver 클래스를 만들었다. publisher에서 이벤트가 생기면 update()가 호출되고, NewsObserver는 이벤트 메세지를 받아 콘솔에 출력한다.


public class App {
public static void main(String[] args) {
NewsPublisher newsPublisher = new NewsPublisher();
NewsObserver newsObserver = new NewsObserver(newsPublisher);
newsPublisher.notifyObserver("[속보] 큰일남");
newsObserver.withdraw();
newsPublisher.notifyObserver("[속보] 완전 큰일남");
}
}
//실행 결과
뉴스
->[속보] 큰일남

위와 같은 코드를 실행하면 newsPublisher의 이벤트를 newsObserver가 받아서 잘 출력되는 것을 볼 수 있다. withdraw()를 호출하면 observers에서 newsObserver가 삭제되기 때문에 더이상 이벤트에 반응하지 않는다.

링크로 가면 코드를 볼 수 있다.