책너두 (헤드 퍼스트 디자인 패턴) 6일차 (~101p)
- Book/헤드 퍼스트 디자인 패턴
- 2023. 7. 3.
요약
- 객체들에게 연락 돌리기 (옵저버 패턴) 계속
- 옵저버 패턴의 정의
- 옵저버 패턴의 구조
- 느슨한 결합의 위력
- 기상 스테이션 구현하기
- Subject 인터페이스 구현하기
- 디스플레이 요소 구현하기
메모
옵저버 패턴의 정의
📍 옵저버 패턴(Observer Pattern) : 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체에게 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성을 정의함.
- 주제와 옵저버로 일대다 관계가 정의됨.
- 옵저버는 주제에 딸려있음.
- 옵저버 패턴의 경우, 보통 주제 인터페이스와 옵저버 인터페이스가 들어있는 클래스 디자인으로 구현됨.
옵저버 패턴의 구조
- 주제를 나타내는 Subject 인터페이스
- 각 주제마다 여러개의 옵저버가 있을 수 있음.
- 옵저버가 될 가능성이 있는 객체는 Observer 인터페이스를 구현해야 함.
- update() 메소드를 구현해야 함.
- 주체 상태가 바뀌면 해당 메소드를 호출함.
- 주제 역할을 하는 구상 클래스는 Subject 인터페이스를 구현해야 함.
느슨한 결합의 위력
- 느슨한 결합 : 객체들이 상호작용할 수는 있지만, 서로를 잘 모르는 관계임.
- 유연성이 아주 좋아짐.
- 옵저버 패턴이 느슨한 결합을 보여주는 훌륭한 예임.
- 주제는 옵저버가 특정 인터페이스(Observer 인터페이스)를 구현한다는 사실만 암.
- 옵저버는 언제든지 새로 추가할 수 있음.
- 새로운 형식의 옵저버를 추가할 때도 주제를 변경할 필요가 전혀 없음.
- 주제와 옵저버는 서로 독립적으로 재사용할 수 있음.
- 주제나 옵저버가 달라져도 서로에게 영향을 미치지 않음.
📍 디자인 원칙 : 상호작용하는 객체 사이에는 가능하면 느슨한 결합을 사용해야 한다. 느슨하게 결합하면, 변경 사항이 생겨도, 무난히 처리할 수 있는 유연한 객체지향 시스템을 구축할 수 있음. 왜냐면 객체 사이의 상호 의존성을 최소화하기 때문
기상 스테이션 구현하기
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
public interface Observer {
public void update(float temp, float humidity, float pressure);
}
public interface DisplayElement {
public void display();
}
- 주제는 옵저버를 등록하고, 제거하는 역할을 가져야 함.
- 주제 상태가 변경되면 모든 옵저버에게 변경 내용을 알리는 메소드를 구현해야 함.
- 옵저버의 update 메소드인자는 기상 정보가 변경될 때 옵저버에게 전달되는 상태값임.
Subject 인터페이스 구현하기
public class WeatherData implements Subject {
private List<Observer> observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList<Observer>();
}
public void removeObserver(Observer o) {
observers.remove(o);
}
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
}
public void measurementsChanged() {
notifyObservers();
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
// 기타 WeatherData 메소드
}
- WeatherData 는 주제의 구상 클래스임.
- 온도, 습도, 기압과 옵저버 객체들을 가지고 있음.
- 기상 스테이션에서 가상 데이터를 가져올 때, setMeasurements 메서드가 호출됨.
- 그러면 새로운 측정 값이 갱신되고, 모든 옵저버에 notify 함.
디스플레이 요소 구현하기
public class CurrentConditionsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private WeatherData weatherData;
public CurrentConditionsDisplay(WeatherData weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
public void display() {
System.out.println("Current conditions: " + temperature
+ "F degrees and " + humidity + "% humidity");
}
}
- 옵저버 구상 클래스는 Observer 를 반드시 구현해야 함.
- update가 호출되면 온도와 습도를 저장하고, display를 호출함.
- update 메소드에 display 메소드를 호출하는 방법은 지금과 같이 간단한 경우에는 괜찮아 보임.
- 하지만, 더 좋은 방법은 12장 모델-뷰-컨트롤러 패턴을 배울때 자세히 살펴봄.
- 주제 레퍼런스를 저장하는 이유는 나중에 옵저버 목록에서 탈퇴할 때 유용하게 쓸 수 있음.
기상 스테이션 테스트
- p97~98 참고
'Book > 헤드 퍼스트 디자인 패턴' 카테고리의 다른 글
책너두 (헤드 퍼스트 디자인 패턴) 8일차 (~125p) (0) | 2023.07.06 |
---|---|
책너두 (헤드 퍼스트 디자인 패턴) 7일차 (~113p) (0) | 2023.07.05 |
책너두 (헤드 퍼스트 디자인 패턴) 5일차 (~86p) (0) | 2023.07.03 |
책너두 (헤드 퍼스트 디자인 패턴) 4일차 (~69p) (0) | 2023.07.01 |
책너두 (헤드 퍼스트 디자인 패턴) 3일차 (~55p) (0) | 2023.06.30 |