옵저버 디자인 패턴

옵저버 디자인 패턴


옵저버 패턴은 신문으로 예를 들어보자. 신문의 출판사와 구독자가 있을 것이다.

출판사는 신문을 출판하고, 구독자는 출판사에 구독 신청을 하면 신문이 나올때마다 해당 신문을 배달받을 수 있다. 구독자로 있는 한, 신문이 나올때 마다 구독할 수 있다.
신문을 구독하고 싶지 않으면 해지를 신청하고, 더 이상 신문이 나와도 구독받지 않는다.

옵저버 패턴에서 출판사를 주제, 구독자를 옵저버라고 부른다.
주제의 데이터가 달리지면 등록한 옵저버들에 대해 소식이 전해진다.

옵저버 패턴의 정의는 한 객체의 상태가 바뀌면, 그 객체에 의존하는 다른 객체들에게 자동으로 내용이 갱신되는 일대다 의존성을 정의한다.

아래를 보자.
인터페이스 Subject를 구현하는 주제(NewsSubject)와 Observer 인터페이스를 구현하는 NewsObserverA와 NewsObserverB가 있다.

주제(NewsSubject)는 옵저버들을 추가/삭제하는 registerObserver와 removeObserver 메소드를 구현하며, 데이터가 변경될 경우 옵저버에게 알리는 notifyObserver 메소드를 구현한다. 주제의 데이터가 변경될 경우 Observer 인터페이스를 구현하는 모든 클래스들은 update 메소드를 통해 변경된 데이터를 다룰 수 있다.


아래 코드는 실제로 동작하진 않지만 위 클래스 구성도를 구현하면 이렇다 라는 개념으로 코딩하였다.

Subject 인터페이스를 정의하고, NewsSubject class가 구현하도록 하였다. NewsSubject는 각 옵저버들을 추가/삭제하는 기능을 구현하고 데이터 변경 시, 각 옵저버들의 update 함수를 호출함으로써 옵저버 패턴을 구현할 수 있다.

public interface Subject {
 public void registerObject(Observer o);
 public void removeObject(Observer o);
 public void notifyObject();
}

public class NewsSubject implements Subject {
 private ArrayList observers;
 private int news;
 
 public void registerObject(Observer o) {
  Observer.add(o);
 }
 
 public void removeObject(Observer o) {
  Observer.remove(o);
 }
 
 public void notifyObject() {
  for(int i=0; i<observers.size(); i++) {
   Observer observer = (Observer)observers.get();
   observer.update(news);
  }
 }
 
 public void makeNews(int news) {
  this.news = news;
  notifyObject();
 }
}

아래는 Observer 인터페이스를 선언하고 NewsObserverA 클래스에서 Observer를 구현하였다. 
NewsSubject 주제가 makeNews를 통해 새로운 신문을 출판하면 각 옵저버의 update(news) 함수를 호출하고,
옵저버는 해당 데이터를 수신하여 자신이 원하는 일을 할 수 있다.

public interface Observer {
 public void update(int news);
}

public class NewsObserverA implements Observer {
 private int news;
 private Subject newsSubject;
 
 public NewsObserverA(Subject newsSubject) {
  this.newsSubject = newsSubject;
 }
 
 public void update(int news) {
  this.news = news;
  
  // do somethig by news
 }
}


느슨한 결합 (loose coupling)

두 객체가 느슨하게 결합되어 있다는 건, 둘의 상호작용을 서로가 잘 모른다는 의미
옵저버 패턴에서는 주제와 옵저버가 서로 느슨하게 결합 됨

왜그럴까?
- 주제가 옵저버에 대해 하는건 특정 인터페이스(Observer)를 구현한다는 것만 알고있음
- 옵저버는 언제든지 새로 추가될 수 있다. 추가 된 Observer는 Observer 인터페이스만 구현하면 주제를 전혀 변경할 필요가 없다.

댓글 없음:

댓글 쓰기