Observer Pattern 이란?

  • 한 객체의 상태가 변화하면 객체에 상속되어 있는 다른 객체들에게 변화된 상태를 전달
  • 일대다 관계를 가진다.
  • 분산된 시스템 간 이벤트를 생성, 발행(Publish) 하고, 이를 수신(Subscribe) 해야 할 때 이용

  • Subject
    Observable 이라고 부르며 이벤트가 발생하는 객체, Observer의 리스트를 가지고 있다.
    Observer의 등록/해제 메서드를 이용하여 Subject를 등록/해제할 수 있다.

  • Observer : Subject의 이벤트를 관찰하는 대상, 이벤트 발생 시 연결된 하위 대상에게 알려줌
  • ConcreteObserve : 각자 역할을 수행하면서 Observer를 통해 Subject의 이벤트를 감지

옵저버 패턴 적용

Subject - 옵저버를 등록/해제, 이벤트 발생 시 옵저버들에게 알려주는 기능

  • Youtuber - 옵저버를 관리해줄 List를 가지고 있으며 Subject 인터페이스의 기능을 구현
package BehavioralPattern.Observer;
import java.util.Observer;

public interface Subject {
    public void registerObserver(Observer observer);
    public void unregisterObserver(Observer observer);
    public void notifyObservers(String msg);
}
package BehavioralPattern.Observer;
import java.util.ArrayList;
import java.util.List;

public class Youtuber implements Subject{
    private List<Observer> subscriberList;
    public Youtuber() {
        subscriberList = new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer observer) {
        subscriberList.add(observer);
    }

    @Override
    public void unregisterObserver(Observer observer) {
        subscriberList.remove(observer);
    }

    @Override
    public void notifyObservers(String msg) {
        for (Observer observer : subscriberList) {
            observer.notifySubscriber(msg);
        }

    }
}

Observer - 자신을 구현한 하위 클래스에게 Subject의 이벤트를 알려주는 기능

package BehavioralPattern.Observer;

public interface Observer {
    public void notifySubscriber(String msg);
}

ConcreteObserve - 각자 역할을 수행하면서 Observer를 통해 Subject의 이벤트를 감지

package BehavioralPattern.Observer;

public class SubscriberA implements Observer{
    @Override
    public void notifySubscriber(String msg) {
        System.out.println(this.getClass() + " : " + msg);
    }
}

public class SubscriberB implements Observer{
    @Override
    public void notifySubscriber(String msg) {
        System.out.println(this.getClass() + " : " + msg);
    }
}

Main & 실행결과

package BehavioralPattern.Observer;

public class Main {
    public static void main(String[] args) {
        Youtuber youtuber = new Youtuber();
        Observer subscriberA = new SubscriberA();
        Observer subscriberB = new SubscriberB();

        System.out.println("SubA 구독");
        youtuber.registerObserver(subscriberA);
        System.out.println("SubB 구독");
        youtuber.registerObserver(subscriberB);

        youtuber.notifyObservers("New video update");
    }
}


자바에서 제공하는  Observer 인터페이스와 Observable 클래스 활용

  • Subject / notifyObservers - Observer 인터페이스 활용
package BehavioralPattern.Observer.Util;
import java.util.Observable;

public class Youtuber extends Observable {

    //별도의 메서드를 하나 구현
    //Observable 클래스는 동기화를 위해 changed 변수가 true 일 때만 notifyObservers() 메서드가 호출
    public void notifyEvent(String msg){
        setChanged();
        notifyObservers(msg);
    }
}
  • ConcreteObserve - Observer 클래스 사용
package BehavioralPattern.Observer.Util;
import java.util.Observable;
import java.util.Observer;

public class SubscriberA implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        System.out.println(this.getClass() + " : " + arg);
    }
}

public class SubscriberB implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        System.out.println(this.getClass() + " : " + arg);
    }
}
package BehavioralPattern.Observer.Util;
import java.util.Observer;

public class Main {
    public static void main(String[] args) {
        Youtuber youtuber = new Youtuber();
        Observer subscriberA = new SubscriberA();
        Observer subscriberB = new SubscriberB();

        System.out.println("SubA 구독");
        youtuber.addObserver(subscriberA);
        System.out.println("SubB 구독");
        youtuber.addObserver(subscriberB);

        youtuber.notifyEvent("New video update");
    }
}


  • 자바 내장기능을 사용하면, 다중상속이 불가능
  • 직접 구현하면 까다로움 , 동기화 문제 처리

참고

https://sorjfkrh5078.tistory.com/category/IT%20%EA%B0%9C%EC%9D%B8%20%EA%B3%B5%EB%B6%80/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4

+ Recent posts