public void static main/Etc

[Design Pattern] Observer Pattern

햄리뮤 2021. 11. 7. 01:45
반응형

오늘은 발표준비겸 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

 

 

 

 

 

 

 

 

 

 

 

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

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

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

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

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

반응형