본문 바로가기

자바

[자바] 옵저버패턴 : java.util.Observer, Observable

이전 포스팅

https://dev-jones.tistory.com/154

 

[자바] Observer 패턴

'관찰자' 관찰하는 객체를 'Observer' 인터페이스를 구현하도록 하고, 관찰하려는 객체는 'Observable'을 상속한다. 다음예제는 난수를 만들고 이를 'Observer'가 관찰하고, 그 수를 출력하도록 한다. packa

dev-jones.tistory.com

에서는 Observer 인터페이스를 직접 구현해 사용했었다.

이번에 소개할 내용은 이미 존재하는 java.util.Observer 인터페이스와 java.util.Observable 클래스를 직접 이용하여 똑같은 예제를 다른 코드로 작성하였다.

Observable클래스의 setChanged메소드와 발생한 난수가 notifyObservers 메소드의 파라미터가 된다는 사실에 주목해보자.

또한 이전에는 getNumber를 통해 발생한 난수를 가져왔지만, 

Observer 인터페이스의 경우, 두번째 인자값으로 해당 난수를 전달하게 된다.

다음은 Observable의 notifyObservers(Object arg) 메소드이다.

public void notifyObservers(Object arg) {

	Object[] arrLocal;

	synchronized (this) {
		if (!changed)
			return;
		arrLocal = obs.toArray();
		clearChanged();
	}

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

 

예제.

package observer2;

import java.util.Observable;

public abstract class NumberGenerator extends Observable {
	public abstract void execute();
}
package observer2;

import java.util.Random;

public class RandomNumberGenerator extends NumberGenerator {

	private Random random = new Random();
	private int number;

	@Override
	public void execute() {
		for (int i = 0; i < 20; i++) {
			setChanged();
			number = random.nextInt(50);
			notifyObservers(number);
		}
	}

}
package observer2;

import java.util.Observable;
import java.util.Observer;

public class DigitObserver implements Observer {

	@Override
	public void update(Observable o, Object arg) {
		System.out.println("DigitObserver : " + arg);
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
package observer2;

import java.util.Observable;
import java.util.Observer;

public class GraphObserver implements Observer {

	@Override
	public void update(Observable o, Object arg) {
		System.out.print("GraphObserver :");
		int count = (int) arg;
		for (int i = 0; i < count; i++) {
			System.out.print("*");
		}
		System.out.println();
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
package observer2;

import java.util.Observer;

public class Main {
	public static void main(String[] args) {
		NumberGenerator generator = new RandomNumberGenerator();
		Observer observer1 = new DigitObserver();
		Observer observer2 = new GraphObserver();
		
		generator.addObserver(observer1);
		generator.addObserver(observer2);
		generator.execute();
	}
}

 

결과:

GraphObserver :**********************************************
DigitObserver : 46
GraphObserver :***********************************
DigitObserver : 35
GraphObserver :*************************************
DigitObserver : 37
GraphObserver :**********
DigitObserver : 10
GraphObserver :***************
DigitObserver : 15
GraphObserver :*******************************
DigitObserver : 31
GraphObserver :*****
DigitObserver : 5
GraphObserver :********************
DigitObserver : 20
GraphObserver :
DigitObserver : 0
GraphObserver :*******************
DigitObserver : 19
GraphObserver :*******************
DigitObserver : 19
GraphObserver :***********************************
DigitObserver : 35
GraphObserver :*********
DigitObserver : 9
GraphObserver :*********************************************
DigitObserver : 45
GraphObserver :*******************
DigitObserver : 19
GraphObserver :*******************************************
DigitObserver : 43
GraphObserver :**********************************
DigitObserver : 34
GraphObserver :**************************************
DigitObserver : 38
GraphObserver :********************************
DigitObserver : 32
GraphObserver :**************************************
DigitObserver : 38

'자바' 카테고리의 다른 글

람다 표현식과 this 키워드에 관하여  (0) 2021.09.26
자바 Stream API  (0) 2021.09.25
[자바] Chain of Responsibility 패턴  (0) 2021.06.16
[자바] Template Method 패턴  (0) 2021.06.14
InputStream과 InputStreamReader  (0) 2021.06.13