Observer Pattern(옵저버 패턴)
옵저버 패턴
- 출판사(주체)와 구독자(옵저버) 의 느슨한 관계?..
시나리오
Head First 디자인패턴 참조 p.78~p.81 고객사로 부터 부탁받은
날씨측정하는 메소드
getTemparture()
getHumididy()
화면출력용 메소드 3개
currentConditionsDisplay(temp,humidity)
statisticsDisplay(temp,humidity)
forecastDisplay(temp,humidity)
1.날씨 측정하는 클레스
임시로 구현한 메소드들
public class WeatherData {
public void measurementsChanged(){
float temp = getTemperature();
float humidity = getHumidity();
//화면출력부분
currentConditionsDisplay(temp,humidity);
statisticsDisplay(temp,humidity);
forecastDisplay(temp,humidity)개
}
//임시구현
private float getTemperature(){
return (float) 17.1;
}
private float getHumidity(){
return (float) 55.5;
}
private void currentConditionsDisplay(float temp, float humididy){
System.out.println("온도:"+temp+"습도:"+humididy);
}
private void statisticsDisplay(float temp, float humididy){
System.out.println("온도:"+temp+"습도:"+humididy);
}
private void forecastDisplay(float temp, float humididy){
System.out.println("온도:"+temp+"습도:"+humididy);
}
이런식으로 연결하면 화면이 추가될때마다 , 매번 코드를 수정해줘야함
(화면 출력부분 주석밑에)
2.더 좋은 방법이 없을까?
느슨한 관계로 묶어보자!
a.Subject 와 Observer 인터페이스 만들기!
interface Observer{
public void update(float temp, float humidity);
}
public interface Subject {
public void registerObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObserver();
}
//자주 중복되는 Display부분도 인터페이스로 만들기
interface DisplayElement{
public void display();
}
b.Subject 상속받기
public class WeatherData implements Subject{
private List<Observer> observers;
private float temp;
private float humidity;
public WeatherData() {
observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObserver() {
for( Observer observer : observers){
observer.update(temp,humidity);
}
}
public void measurementsChanged(){
notifyObserver();
}
public void setMeasurements(float temp, float humidity){
this.temp = temp;
this.humidity = humidity;
measurementsChanged();
}
}
b.Observer 상속받기(Display도)
class CurrentConditionsDisplay implements Observer, DisplayElement{
private float temp;
private float humidity;
private Subject weatherData;
//옵저버 등록하는 생성자
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void update(float temp, float humidity) {
this.temp = temp;
this.humidity = humidity;
display();
}
@Override
public void display() {
System.out.printf("온도:"+this.temp);
System.out.printf("습도:"+this.humidity);
System.out.println();
}
}
테스트
public static void main(String[] args) {
WeatherData2 wd = new WeatherData2();
CurrentConditionsDisplay cd = new CurrentConditionsDisplay(wd);
wd.setMeasurements((float) 30,(float) 44.5);
wd.setMeasurements((float) 20,(float) 24.5);
wd.setMeasurements((float) 10,(float) 64.5);
}
콘솔창
온도:30.0습도:44.5
온도:20.0습도:24.5
온도:10.0습도:64.5
디자인 패턴 목록