본문 바로가기

디자인패턴

JAVA에서의 Observer 패턴

728x90

옵저버 패턴을 구현

public class subjectimple extends Observable {
	void eatFood() {
		System.out.println("밥 먹는 다");
		setChanged();
		notifyObservers("밥");
	}
}

notifyObservers: 구독자들에게 상태전달

setChanged: 내부 플래그를 true로 만들어 알림이 동작하게 함

observable 클래스

public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;

    /** Construct an Observable with zero Observers. */

    public Observable() {
        obs = new Vector<>();
    }

// ... 중략

obs라는 observer들의 집합을 가지고 있으며

changed라는 flag 변수를 가지고 있음

옵저버 추가하는 함수

public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }
출처: <https://pjh3749.tistory.com/266> [JayTech의 기술 블로그:티스토리]

notify 하는 함수

public void notifyObservers(Object arg) {
        /*
         * a temporary array buffer, used as a snapshot of the state of
         * current Observers.
         */
        Object[] arrLocal;

        synchronized (this) {
            /* We don't want the Observer doing callbacks into
             * arbitrary code while holding its own Monitor.
             * The code where we extract each Observable from
             * the Vector and store the state of the Observer
             * needs synchronization, but notifying observers
             * does not (should not).  The worst result of any
             * potential race-condition here is that:
             * 1) a newly-added Observer will miss a
             *   notification in progress
             * 2) a recently unregistered Observer will be
             *   wrongly notified when it doesn't care
             */
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

flag 변수를 통해 synchronized를 보장

  • 벡터를 꺼내고 저장하는 과정은 동기화가 필요
  • 옵저버들에게 통보하는 과정은 동기화 필요 없음
    • 그래서 update함수는 동기화 블럭 밖에 있음
  • 마지막에 clearChanged를 통해 flag를 다시 false로 변환

Observer 인터페이스

public interface Observer {
    /**
     * This method is called whenever the observed object is changed. An
     * application calls an Observable object's
     * notifyObservers method to have all the object's * observers notified of the change. * * @param o the observable object. * @param arg an argument passed to the notifyObservers * method. */ void update(Observable o, Object arg); } 출처: <https://pjh3749.tistory.com/266> [JayTech의 기술 블로그:티스토리]

observable은 상속 해서 사용해야 되는 데 자바는 다중상속을 지원하지 않아

인터페이스로 직접 구현하는 것도 나쁘지 않음

728x90

'디자인패턴' 카테고리의 다른 글

Composite 패턴이란?  (0) 2024.05.23
State Pattern (상태패턴) 이란?  (0) 2024.04.25
데코레이터 (Decorator) 패턴이란?  (0) 2024.02.20
옵저버 패턴 (Observer pattern) 이란?  (0) 2024.02.09
Strategy Pattern  (0) 2024.01.22