Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- SWIFT
- WKWebView
- 전략패턴
- 싱글턴패턴
- Mobile
- 이터레이터패턴
- 커맨드패턴
- Scenedelegate
- 옵저버패턴
- RxSwift
- 컴포지트패턴
- 파사드패턴
- ios
- 스테이트패턴
- Xcode
- 데코레이터패턴
- 프록시패턴
- 팩토리메서드패턴
- 디자인패턴
- 컴파운드패턴
- 추상팩토리패턴
- unowned
- 상태패턴
- Lifecycle
- cocoapods
- 어댑터패턴
- 스트래터지패턴
- DispatchQueue
- 템플릿메서드
- ViewController
Archives
- Today
- Total
ios dev kangwook.
02. Observer Pattern 본문
객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 알림을 주도록 하는 디자인 패턴
Observer Pattern
Observer Pattern은 객체 간의 일대다(one to many) 의존성을 정의하여 하나의 객체가 상태를 변경할 때 모든 종속자에게 자동으로 알림과 업데이트를 제공한다.
- Subject : Observer를 알고 있는 주체. Observer를 등록하고 제거하는 데 필요한 인터페이스를 정의
- Observer : Subject에서 변화했다고 알렸을 때 갱신해야하는데 필요한 인터페이스를 정의
- ConcreteSubject : 객체(Observer)에게 알려줘야할 상태를 지정, notify 해야할 함수를 만들도록 함
- ConcreteObserver : update를 했을 경우 행동할 로직 작성
- Loose Coupling(느슨한 결합)
- 주체와 옵저버가 느슨하게 결합
- 옵저버는 언제든 추가 / 제거 가능
- 새로운 형식의 옵저버를 추가해도 주체를 변경할 필요가 없음
- 주체와 옵저버는 서로 독립적으로 재사용 가능
- 주체나 옵저버가 바뀌더라도 서로에게 영향을 미치지 않음
Observer Pattern 예제
- Weather-O-Rama 사의 기상 모니터링 애플리케이션
- WeatherData 객체를 사용해 현재조건, 기상통계, 기상예측 세 항목을 디스플레이에 갱신해 보여주는 애플리케이션
- 기상 정보를 수집하는 기상 스테이션
- WeatherData 객체
- 기상조건을 보여주는 디스플레이로 이루어짐
- update 메서드의 temp, humidity, pressure은 Subject로부터 상태가 날씨 측정값이 바뀌었을경우 받아오는 상태 값
- Subject의 상태가 바뀌었을 경우에 notify를 통해 모든 옵저버들에게 알림
public interface Subject {
// 옵저버 등록(추가), 제거, 호출
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObserver(Observer o);
}
public interface Observer {
// 기상정보가 변경되었을 때 옵저버에게 전달되는 값
public void update(float temp, float humidity, float pressure);
}
public interface DisplayElement {
// 화면 표시
public void display();
}
- Subject를 구현한 WeatherData
public class WeatherData implements Subject {
private ArrayList<Observer> observers; // 옵저버 객체 저장
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList<Observer>();
}
public void registerObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
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();
}
...
}
- 변경사항을 받기 위한 Observer, 디스플레이 항목 구현
public class CurrentConditionsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private Subject weatherData;
// 생성자에 주체 객체 전달, 옵저버로 등록
public CurrentCoditionsDisplay(Subject 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");
}
}
Java의 Observable을 이용한 Observer Pattern
- Java에 내장되어있는 Observable은 interface가 아닌 Class
- setChanged() 메서드는 상태가 바뀌었다는 것을 알기 위한 용도 → java의 Observable에서는 setChanged()를 하지 않으면 notifyObservers()를 호출한다해도 옵저버들에게 알림이 가지 않음. → setChanged()가 일종의 필터(중간다리)역할
- WeatherData에서는 더이상 observer를 등록해주거나 삭제, 알려주는 메서드를 작성할 필요가 없음
- java.util.Observable의 단점
- Observable은 class 이기 때문에 다중상속이 불가능하므로 다른 클래스를 상속하는 클래스는 Observable의 자식클래스가 될 수 없음
- setChanged() 메서드는 protected로 선언되어 있는데 이는 즉, Observable를 상속받는 클래스가 아니면 setChanged를 호출할 수 없음.
→ Observable을 상속받는 객체를 다른 패키지에서 인스턴스 변수로 써먹을 수 없음
→ 이는 ‘상속보다는 구성하라(favor composition over inheritance)’ 디자인 설계 원칙에 어긋남
결론
- Observer Pattern은 행위 패턴(Behavioral Pattern)의 하나로써 한 객체의 상태 변화에 따라 다른 객체의 상태도 연동되도록(알려주도록) 일대 다 객체 의존 관계를 구성하는 패턴
- 장점
- 느슨한 결합으로 인하여 시스템이 유연해지고 객체간의 의존성을 제거할 수 있음
- 실시간으로 한 객체의 변경사항을 다른 객체에 전달할 수 있음
- 단점
- Thread safe하지 않아서 observer를 등록 / 제거 하는 동안 원하는 결과값을 얻기 힘들 수 있음
- observer를 제 때 제거해주지 않으면 메모리 누수가 일어날 수 있음
- 너무 많이 사용하게 되면 상태 관리가 힘들 수 있음
본문은 Head First Design Pattern (2004) 를 참고하여 공부하고 작성하였습니다.
'Design Pattern' 카테고리의 다른 글
06. Singleton Pattern (0) | 2022.08.21 |
---|---|
05. Abstract Factory Pattern (0) | 2022.08.20 |
04. Factory Method Pattern (0) | 2022.08.18 |
03. Decorator Pattern (0) | 2022.04.30 |
01. Strategy Pattern (0) | 2022.03.12 |
Comments