옵저버 패턴


옵저버 패턴은 흔히 출판사-구독자의 관계로 설명된다.

예를 들어, A출판사에서 발행하는 신문기사가 아주 유용하다치자, A출판사에서 발행하는 신문을 받아볼려면 구독을 해야겠지?

그러면 정기적으로 A출판사가 발행하는 신문기사를 받아볼 수 있게 된다.

 

위의 내용에서 A출판사는 어떤 데이터의 갱신 또는 생성과 같은 이벤트가 발생하면 구독자에게 전달하는 객체.

구독자는 어떤 데이터의 갱신 또는 생성과 같은 이벤트가 발생했음을 A출판사로부터 알림받는 객체.

 

[그림 1] 옵저버 패턴

 

옵저버 패턴을 구현하는 방법은 여러 가지가 있지만, 일반적으로 Subject 인터페이스, Observer 인터페이스가 들어있는 클래스 디자인을 바탕으로 한다.

 

Entry 포인터를 잡고

public class Main {

    public static void main(String[] args) {
        System.out.println("Enter Text >");

        // 이벤트 발행 주체를 생성함 - stdin으로부터 문자열을 입력받음
        final EventSource evSrc = new EventSource();

        // 옵저버를 생성함
        final ResponseHandler respHandler = new ResponseHandler();

        // 옵저버가 발행 주체가 발행하는 이벤트를 구독하게 함
        evSrc.addObserver(respHandler);

        // 이벤트를 발행시키는 쓰레드 시작
        Thread thread = new Thread(evSrc);
        thread.start();
    }
}

 

A출판사에 해당하는 Subject 객체

public class EventSource extends Observable implements Runnable {

    @Override
    public void run() {
        try {
            final InputStreamReader isr = new InputStreamReader(System.in);
            final BufferedReader br = new BufferedReader(isr);
            while (true) {
                final String response = br.readLine();
                setChanged();
                notifyObservers(response);
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

구독자에 해당하는 Observer 객체

public class ResponseHandler implements Observer {

    private String resp;

    public void update (Observable obj, Object arg) {
        if (arg instanceof String) {
            resp = (String) arg;
            System.out.println("\nReceived Response: "+ resp );
        }
    }
}