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>();   
}

@Override
public void registerObserver(JMObserver o) { // 옵저버 등록
observers.add(o);
}
@Override
public void removeObserver(JMObserver o) { // 옵저버 삭제
int i= observers.indexOf(o);
if(i >= 0){
observers.remove(i);
}
}
@Override
public 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 JMObserverJMDisplayElement {
private float temperature;
private float humidity;
private JMSubject weatherData;

public JMCurrentConditionsDisplay(JMSubject weatherData) {
   // 생성자에 weatherData 라는 주제 객체가 전달되며, 그 객체를 써서 디스플레이를 옵저버로 등록합니다.
this.weatherData = weatherData;
weatherData.registerObserver(this);

}
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature = temp;
this.humidity = humidity;
display();
}
@Override
public void display() {
System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
}

}

6. 두번째 옵저버클래스를 만듭니다.
public class JMForcecastDisplay implements JMObserverJMDisplayElement{
private float currentPressure = 29.92f;  
private float lastPressure;
private JMWeatherData weatherData;
public JMForcecastDisplay(JMWeatherData wea) {  // 생성자에 JMWeatherData wea 을 넣어둠으로써
   //메인에서 객체 생성시 wea 객체를 넣어줘야함
this.weatherData = wea;
wea.registerObserver(this);
}
@Override
public void update(float temp, float humidity, float pressure) {
lastPressure = currentPressure;
currentPressure = pressure;
display();
}
@Override
public 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

댓글

이 블로그의 인기 게시물

전자정부프레임워크 MSSQL 연동하기

request.getServletContext 가 빨간줄 생길때

자바스크립트로 confirm 을 이용한 페이지 이동