오늘은 발표준비겸 Observer Pattern이 무엇인지 알아보자!
옵저버 패턴이 뭔가 찾다가 진짜 엄청난 블로그를 발견했다! 덤으로 좋은 책도 발견!
Head First Design Patterns 책이다! 궁금하시분은 찾아보시길! (광고 아닙니다~!!!)
나를 단번에 이해 시켜주셨다! 출처는 맨아래!
Observer Pattern이 뭐야?
- 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고, 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many)의존성을 정의한다.
🔴잠깐!🔴
일대 다(one-to-many) 관계ㅖㅖㅖ?
- 옵저버 패턴에서 상태를 저장하고 지배하는 것은 주제(Subject) 객체이다. 따라서 상태가 들어있는 객체는 하나만 있을 수 있다.
- 옵저버는 사용하긴 하지만 반드시 상태를 가지고 있어야 하는 것은 아니므로 옵저버는 여러개가 있을 수 있고,
주제(Subject) 객체에서 상태가 바뀌었다는 것을 알려주기를 기다리는 주제(Subject)에 의존적인 성질을 가지게 된다.
✅하나의 주제와 여러개의 옵저버가 연관된 일대다(one-to-many) 관계가 성립된다!
간단한 예를 들어보면 유명한 가수가 공연을 한다! 라고 팬 카페에 공지를 하면 그 카페에 가입하고있는 많은 팬들은 공연 공지에 대한 알림을 받을 것이다!
여기서 알림을 주는 가수 입장을 Subject 라고 하고
알림을 받는 팬 입장을 Observer 라고 보면 된다!
느슨한 결합(Loose Coupling)
- 두 객체가 느슨하게 결합되어 있다는 것은, 그 둘이 상호작용을 하긴 하지만 서로에 대해 잘 모른다는 것을 의미한다. 옵저버 패턴에서는 Subject와 옵저버가 느슨하게 결합되어 있는 객체 디자인을 제공한다!
- Subject가 옵저버에 대해서 아는것은 옵저버가 특정 인터페이스 (Observer 인터페이스)를 구현한다는 것 뿐이다!
- 옵저버의 구상클래스가 무엇인지, 옵저버가 무엇을 하는지 등에 대해서는 알 필요가 없음!
- 옵저버는 언제든지 새로 추가할 수 있다!
- Subject는 Observer 인터페이스를 구현하는 객체의 목록에만 의존하기 때문에 언제든지 새로운 옵저버를 추가하거나 기존 옵저버를 제거하거나 등의 작업을 할 수 있다!
- 새로운 형식의 옵저버를 추가하려고 할 때도 Subject를 전혀 변경할 필요가 없다!
- 새로운 클래스에서 Observer 인터페이스를 구현하고 옵저버로 등록하기만 하면 된다!
- Subject와 옵저버는 서로 독립적으로 재사용할 수 있다!
- Subject와 옵저버가 서로 단단하게 결합되어 있지 않기 때문에 다른 용도로 손쉽게 재사용이 가능하다!
- Subject나 옵저버가 바뀌더라도 서로한테 영향을 미치지 않는다!
- 둘이 서로 느슨하게 결합되어 있기 때문이다!
자~ 이제 옵저버 코드를 구현하면서 익혀보자!
[필요한 요소]
1. 실제 기상 정보를 수집하는 기상 스테이션 (Weather Station)
2. 기상 스테이션으로부터 오는 데이터를 추적하는 객체 WeatherData Object
3. 사용자에게 현재 기상 조건을 보여주는 디스플레이 (Displays)
[데이터내용]
1. WeatherDataObject에서 기상 스테이션 장비 자체로부터 데이터를 가져올 수 있음.
2. 데이터를 가져온 후 디스플레이 장비에 세가지 항목을 표시할 수 있음.
3. 디스플레이에 표시되는 내용: 현재날씨(온도, 습도, 압력), 간단한 기상 예보, 기상 통계
[구현할 내용]
WeatherDataObject를 사용하여 현재 날씨, 기상 예보, 기상 통계 세 항목을 디스플레이 장비에서 갱신해 가면서 보여주는 애플리케이션을 만들어야한다! (확장 가능하게)
[기상 스테이션 구조]
Subject
- Observer들을 알고 있는 주체
- Observer 객체를 붙이거나 떼는 데 필요한 인터페이스를 제공
Observer
- Subject에 생긴 변화에 관심 있는 객체를 갱신하는 데 필요한 인터페이스를 정의
- Subject의 변경에 따라 변화되어야 하는 객체들의 일관성을 유지
ConcreteSubject (WeatherData)
- ConcreteObserver 객체에게 알려주어야하는 상태를 저장
- 상태가 변경될 때 Observer에게 변경을 통보
ConcreteObserver
- ConcreteObserver 객체에 대한 참조자(CurrentConditionsDisplay)를 관리
- Subject의 상태와 일관성을 유지해야 하는 상태를 저장
- Subject의 상태와 Observer의 상태를 일관되게 유지하는 데 사용하는 갱신 인터페이스를 구현
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
// Subject 객체의 상태가 변경되었을 때 모든 옵저버들에게 알리기위해 호출되는 메소드
public void notifyObservers();
}
Subject로 부터 업데이트 알림을 받는 Observer
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;
// Observer 객체를 저장하기 위해 ArrayList를 생성자에서 생성한다.
public WeatherData() {
observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
// 모든 옵저버들이 가지고 있는 update() 메소드를 이용하여 옵저버들에게 상태를 갱신
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
}
// 기상 스테이션으로부터 갱신된 측정치를 받으면 옵저버들에게 알리는 notifyObservers()를 호출한다
public void measurementsChanged() {
notifyObservers();
}
// 기상 스테이션으로부터 갱신된 측정치를 받아 갱신 후, measurementsChanged() 호출
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 {
}
public class ForecastDisplay implements Observer, DisplayElement {
}
public class StatisticsDisplay implements Observer, DisplayElement {
}
엥!!? Subject클래스를 찾아보다가 Observable이란 뭔가 비슷하게 생긴 클래스를 찾았다 이름도 Observable야... 뭔가 관련이 있나...?
Observable은 또 뭐야....? 우씨 ╰(‵□′)╯
Subject와 Observable차이는 다음에 알아보자...!
근데 알고싶으시다면 밑의 링크를 참고! 아주 잘 설명해주셨다~
https://sujinnaljin.medium.com/rxswift-subject-99b401e5d2e5
[RxSwift] Subject
Observable이랑 Subject 나만 헷갈려..?
sujinnaljin.medium.com
며칠 후...
그래서 알아봤따...
자바 내장 옵저버 패턴의 단점과 한계
- Obserable은 클래스 이다.
- 서브클래스를 만들어야 한다는 점이 문제이다. 이미 다른 수퍼 클래스를 확장하고 있는 클래스에 Obserable의 기능을 추가할 수 없기 때문이다. 그래서 재상용성에 제약이 생긴다.
- Observable 클래스의 핵심 메솓드를 외부에서 호출할 수 없다.
- Observable API를 살펴보면, setChanged() 메소드가 protected로 선언되어 있다. Observable의 서브 클래스에서만 setChanged()를 호출할 수 있다. 결국 직접 어떤 클래스를 만들고, Observable의 서브클래스를 인스턴스 변수로 사용하는 방법도 쓸 수 없다. 이런 디자인은 상속보다는 구성을 사용한다는 디자인 원칙에도 위배된다.
오늘도 공부에 도움을 주신 멘토분들 너무너무 감사합니다! 수고했다 내 자신도! 빨리 코야하러가자~!
[디자인패턴] 2. 옵저버 패턴 개념과 예제 (observer pattern)
Head First Design Patterns 책을 보고 정리한 내용입니다. 디자인 패턴을 처음 입문하시는 분들께 추천드리고픈 책입니다. >[ 목차 ] 스트래티지 패턴 옵저버 패턴 데코레이터 패턴 팩토리 패턴 싱글턴
velog.io
https://gre-eny.tistory.com/166
Head First: Design Patterns - 옵저버 패턴(Observer Pattern)
디자인 패턴: 옵저버 패턴(Observer Pattern) 이 포스팅은 Head First: Design Patterns 책을 보고, 개인적으로 정리한 포스팅입니다. Observer Pattern 이란? 옵저버 패턴(Observer Pattern) 에서는 한 객체의 상..
gre-eny.tistory.com
https://github.com/PaengE/HeadFirst_DesignPatterns/tree/main/src/headfirst/designpatterns/observer
GitHub - PaengE/HeadFirst_DesignPatterns: Head First: Design Patterns - Study
Head First: Design Patterns - Study. Contribute to PaengE/HeadFirst_DesignPatterns development by creating an account on GitHub.
github.com
** 그냥 하루하루 개인 공부한 것을 끄적 거리는 공간입니다.
이곳 저곳에서 구글링한 것과 강의 들은
내용이 정리가 되었습니다.
그림들은 그림밑에 출처표시를 해놓았습니다.
문제가 될시 말씀해주시면 해당 부분은 삭제 하도록하겠습니다. **
'public void static main > Etc' 카테고리의 다른 글
[Design Pattern] Builder Pattern (0) | 2021.11.09 |
---|---|
[Design Pattern] Flyweight Pattern (0) | 2021.11.09 |
[Design Pattern] Singleton Pattern (0) | 2021.11.02 |
[npm] npm이란 (0) | 2021.05.05 |
[Gradle] Gradle은 무엇일까나 (0) | 2021.05.05 |
댓글