본문 바로가기
public void static main()/Design Pattern

[Design Pattern] Observer Pattern

by 햄리뮤 2021. 11. 7.
반응형

오늘은 발표준비겸 Observer Pattern이 무엇인지 알아보자!

옵저버 패턴이 뭔가 찾다가 진짜 엄청난 블로그를 발견했다! 덤으로 좋은 책도 발견!

Head First Design Patterns 책이다! 궁금하시분은 찾아보시길! (광고 아닙니다~!!!)

나를 단번에 이해 시켜주셨다! 출처는 맨아래!

 

 

https://refactoring.guru/design-patterns/observer

Observer Pattern이 뭐야?

- 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고, 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many)의존성을 정의한다.

 

🔴잠깐!🔴

일대 다(one-to-many) 관계ㅖㅖㅖ?

- 옵저버 패턴에서 상태를 저장하고 지배하는 것은 주제(Subject) 객체이다. 따라서 상태가 들어있는 객체는 하나만 있을 수 있다.

- 옵저버는 사용하긴 하지만 반드시 상태를 가지고 있어야 하는 것은 아니므로 옵저버는 여러개가 있을 수 있고,

주제(Subject) 객체에서 상태가 바뀌었다는 것을 알려주기를 기다리는 주제(Subject)에 의존적인 성질을 가지게 된다.

✅하나의 주제와 여러개의 옵저버가 연관된 일대다(one-to-many) 관계가 성립된다!

 

간단한 예를 들어보면 유명한 가수가 공연을 한다! 라고 팬 카페에 공지를 하면 그 카페에 가입하고있는 많은 팬들은 공연 공지에 대한 알림을 받을 것이다!

 

여기서 알림을 주는 가수 입장을 Subject 라고 하고

알림을 받는 팬 입장Observer 라고 보면 된다!

 

 

https://arjunsk.medium.com/observer-pattern-in-java-43e464249bed

느슨한 결합(Loose Coupling)

- 두 객체가 느슨하게 결합되어 있다는 것은, 그 둘이 상호작용을 하긴 하지만 서로에 대해 잘 모른다는 것을 의미한다. 옵저버 패턴에서는 Subject와 옵저버가 느슨하게 결합되어 있는 객체 디자인을 제공한다!

  • Subject가 옵저버에 대해서 아는것은 옵저버가 특정 인터페이스 (Observer 인터페이스)를 구현한다는 것 뿐이다!
    • 옵저버의 구상클래스가 무엇인지, 옵저버가 무엇을 하는지 등에 대해서는 알 필요가 없음!
  • 옵저버는 언제든지 새로 추가할 수 있다!
    • Subject는 Observer 인터페이스를 구현하는 객체의 목록에만 의존하기 때문에 언제든지 새로운 옵저버를 추가하거나 기존 옵저버를 제거하거나 등의 작업을 할 수 있다!
  • 새로운 형식의 옵저버를 추가하려고 할 때도 Subject를 전혀 변경할 필요가 없다!
    • 새로운 클래스에서 Observer 인터페이스를 구현하고 옵저버로 등록하기만 하면 된다!
  • Subject와 옵저버는 서로 독립적으로 재사용할 수 있다!
    • Subject와 옵저버가 서로 단단하게 결합되어 있지 않기 때문에 다른 용도로 손쉽게 재사용이 가능하다!
  • Subject나 옵저버가 바뀌더라도 서로한테 영향을 미치지 않는다!
    • 둘이 서로 느슨하게 결합되어 있기 때문이다!

Observer interface

 

자~ 이제 옵저버 코드를 구현하면서 익혀보자!

[필요한 요소]

1. 실제 기상 정보를 수집하는 기상 스테이션 (Weather Station)

2. 기상 스테이션으로부터 오는 데이터를 추적하는 객체 WeatherData Object

3. 사용자에게 현재 기상 조건을 보여주는 디스플레이 (Displays)

 

https://faun.pub/head-first-design-patterns-using-go-1-keeping-your-objects-in-the-know-the-observer-pattern-948e6b5b66fc

[데이터내용]

1. WeatherDataObject에서 기상 스테이션 장비 자체로부터 데이터를 가져올 수 있음.

2. 데이터를 가져온 후 디스플레이 장비에 세가지 항목을 표시할 수 있음.

3. 디스플레이에 표시되는 내용: 현재날씨(온도, 습도, 압력), 간단한 기상 예보, 기상 통계

 

[구현할 내용]

WeatherDataObject를 사용하여 현재 날씨, 기상 예보, 기상 통계 세 항목을 디스플레이 장비에서 갱신해 가면서 보여주는 애플리케이션을 만들어야한다! (확장 가능하게)

 

https://velog.io/@hanna2100/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-2.-%EC%98%B5%EC%A0%80%EB%B2%84-%ED%8C%A8%ED%84%B4-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%98%88%EC%A0%9C-observer-pattern

[기상 스테이션 구조]

Subject

  • Observer들을 알고 있는 주체
  • Observer 객체를 붙이거나 떼는 데 필요한 인터페이스를 제공

Observer

  • Subject에 생긴 변화에 관심 있는 객체를 갱신하는 데 필요한 인터페이스를 정의
  • Subject의 변경에 따라 변화되어야 하는 객체들의 일관성을 유지

ConcreteSubject (WeatherData)

  • ConcreteObserver 객체에게 알려주어야하는 상태를 저장
  • 상태가 변경될 때 Observer에게 변경을 통보

ConcreteObserver

  • ConcreteObserver 객체에 대한 참조자(CurrentConditionsDisplay)를 관리
  • Subject의 상태와 일관성을 유지해야 하는 상태를 저장
  • Subject의 상태와 Observer의 상태를 일관되게 유지하는 데 사용하는 갱신 인터페이스를 구현 

 

https://milextone.ir/software-design/design-patterns/observer-pattern

 

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의 서브클래스를 인스턴스 변수로 사용하는 방법도 쓸 수 없다. 이런 디자인은 상속보다는 구성을 사용한다는 디자인 원칙에도 위배된다.

 

 

 

오늘도 공부에 도움을 주신 멘토분들 너무너무 감사합니다! 수고했다 내 자신도! 빨리 코야하러가자~!

 

https://velog.io/@hanna2100/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-2.-%EC%98%B5%EC%A0%80%EB%B2%84-%ED%8C%A8%ED%84%B4-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%98%88%EC%A0%9C-observer-pattern

 

[디자인패턴] 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

 

 

 

 

 

 

 

 

 

 

 

** 그냥 하루하루 개인 공부한 것을 끄적 거리는 공간입니다.

이곳 저곳에서 구글링한 것과 강의 들은

내용이 정리가 되었습니다.

그림들은 그림밑에 출처표시를 해놓았습니다.

문제가 될시 말씀해주시면 해당 부분은 삭제 하도록하겠습니다. **

반응형

댓글