Observer
한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로
일대다 의존성을 정의합니다.
1. 주제 인터페이스를 생성합니다.
public interface JMSubject {
public void registerObserver(JMObserver o); // 옵저버를 등록
public void removeObserver(JMObserver o); // 옵저버 삭제
public void notifyObservers(); //주제 객체의 상태가 변경되었을때 옵저버들에게 알리기 위해 호출되는 매소드
}
2. 옵저버 인터페이스를 만듭니다.
public interface JMObserver {
public void update(float temp, float humidity, float pressure); // 모든 옵저버는 JMObserver 를 구현해야한다
// 옵저버에게 전달되는 값들
}
3. 변경된 화면을 보여주는 인터페이스를 만듭니다.
public interface JMDisplayElement {
public void display(); // 화면보여주기
}
4. 주제 인터페이스를 구현합니다.
public class JMWeatherData implements JMSubject{
private ArrayList<JMObserver> observers; // 등록된 옵져버들private float temperature;private float humidity;private float pressure;
public JMWeatherData() {
observers = new ArrayList<JMObserver>();
}@Overridepublic void registerObserver(JMObserver o) { // 옵저버 등록
observers.add(o);
}@Overridepublic void removeObserver(JMObserver o) { // 옵저버 삭제
int i= observers.indexOf(o);
if(i >= 0){observers.remove(i);}}@Overridepublic void notifyObservers() { // 변한값을 옵저버들에게 데이터 업데이트for(int i=0; i < observers.size(); i++){
JMObserver observer = (JMObserver)observers.get(i);observer.update(temperature, humidity, pressure);
}}public void measurementsChanged(){ // notifyObservers() 호출notifyObservers();}public void setMeasurements(float temperature, float humidity, float pressure){// 임의의 값 넣어주고 measurementsChanged() 호출
this.temperature = temperature;this.humidity = humidity;this.pressure = pressure;measurementsChanged();
}
}
5. 첫번째 옵저버클래스를 만듭니다.
public class JMCurrentConditionsDisplay implements JMObserver, JMDisplayElement {
private float temperature;private float humidity;private JMSubject weatherData;public JMCurrentConditionsDisplay(JMSubject weatherData) {
// 생성자에 weatherData 라는 주제 객체가 전달되며, 그 객체를 써서 디스플레이를 옵저버로 등록합니다.
this.weatherData = weatherData;weatherData.registerObserver(this);
}@Overridepublic void update(float temp, float humidity, float pressure) {
this.temperature = temp;this.humidity = humidity;display();
}@Overridepublic void display() {
System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
}
}
6. 두번째 옵저버클래스를 만듭니다.
public class JMForcecastDisplay implements JMObserver, JMDisplayElement{
private float currentPressure = 29.92f;private float lastPressure;private JMWeatherData weatherData;public JMForcecastDisplay(JMWeatherData wea) { // 생성자에 JMWeatherData wea 을 넣어둠으로써
//메인에서 객체 생성시 wea 객체를 넣어줘야함
this.weatherData = wea;wea.registerObserver(this);
}@Overridepublic void update(float temp, float humidity, float pressure) {
lastPressure = currentPressure;currentPressure = pressure;display();
}@Overridepublic void display() {
System.out.print("Forecast: ");
if (currentPressure > lastPressure) {System.out.println("currentPressure 더 크다");} else if (currentPressure == lastPressure) {System.out.println("똑같다");} else if (currentPressure < lastPressure) {System.out.println("lastPressure 가 더 크다");}
}
}
옵저버클래스를 생성하면 상위 클래스인 JMWeatherData 클래스에 쌓이게됩니다.
7. 메인클래스를 실행합니다.
public class Test1 {
public static void main(String[] args) {JMWeatherData jmWe = new JMWeatherData();JMCurrentConditionsDisplay current = new JMCurrentConditionsDisplay(jmWe);JMForcecastDisplay force = new JMForcecastDisplay(jmWe); // 객체생성시JMWeatherData타입을 넣어줘야함jmWe.setMeasurements(80, 600, 30.4f);System.out.println("");jmWe.setMeasurements(10, 10, 20.4f);jmWe.removeObserver(current); System.out.println("삭제후"); jmWe.setMeasurements(50, 50, 40.4f);// setMeasurements 실행 -> measurementsChanged() 실행 -> notifyObservers() 실행}
}
결과값:
Current conditions: 80.0F degrees and 600.0% humidity
Forecast: currentPressure 더 크다
Current conditions: 80.0F degrees and 600.0% humidity
Current conditions: 10.0F degrees and 10.0% humidity
Forecast: lastPressure 가 더 크다
Current conditions: 10.0F degrees and 10.0% humidity
삭제후
Forecast: currentPressure 더 크다
Current conditions: 50.0F degrees and 50.0% humidity
댓글
댓글 쓰기