Henu
개발냥발
Henu
전체 방문자
오늘
어제
  • 분류 전체보기 (411)
    • DevOps (52)
      • Kubernetes (19)
      • Docker (14)
      • AWS (3)
      • Nginx (4)
      • Linux (4)
      • ArgoCD (1)
      • CN (2)
      • NATS (0)
      • Git (5)
    • Back-End (30)
      • Django (18)
      • Spring (5)
      • JPA (1)
      • MSA (5)
    • CS (87)
      • SystemSoftware (20)
      • OS (25)
      • Computer Architecture (16)
      • Network (23)
      • Database (2)
    • Lang (21)
      • Java (9)
      • Python (4)
      • C# (8)
    • Life (12)
    • 블록체인 (2)
    • Algorithm (204)
      • BOJ (160)
      • 프로그래머스 (19)
      • LeetCode (4)
      • SWEA (1)
      • 알고리즘 문제 해결 전략 (8)
      • DS, algorithms (7)
      • Checkio (5)
    • IT (2)

블로그 메뉴

  • GitHub
  • 글쓰기
  • 관리자

공지사항

  • Free!

인기 글

태그

  • django
  • docker
  • BFS
  • boj
  • Kubernetes
  • 백트래킹
  • 다이나믹 프로그래밍
  • 프로그래머스
  • Network
  • DFS

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Henu

개발냥발

옵저버 패턴 (Observer Pattern)
Lang/Java

옵저버 패턴 (Observer Pattern)

2022. 10. 21. 00:15
옵저버 패턴 (Observer Pattern)

 

객체의 상태 변화을 감지하고 연결된 다른 객체의 상태를 쉽게 변경할 수 있도록 한다.

일대다 의존 관계를 구성해서 하나의 객체가 상태를 변경하면 모든 의존 객체에게 자동으로 알림이 전송되고 업데이트 하는 패턴이다.

 

 

주로 사용하는 곳

알림, 이벤트 기능이 필요한 대부분의 기능에서 해당 패턴을 사용한다.

  • Android의 Event Listener
  • 브라우저의 Event Handler
  • Java Swing 라이브러리(GUI)

이외에도 GUI 프로그래밍을 하거나 메시지 발송과 같은 기능을 사용한다면 옵저버 패턴이 빠질 수 없다.


용어 정리

  • Subject : 상태 변경을 알려주는 객체 (발행인)
  • Observer : 상태 변경에 대한 알림을 받는 객체 (구독자)

 

 

헷갈리는 개념 정리

Publish - Subscribe 패턴(Pub-Sub Pattern)과 관련이 있는가?  Observer 패턴의 또 다른 이름?

 

같은 패턴이 아니다. 


관련은 있지만 Publish-Subscribe 패턴은 '토픽' 이라는 것을 통해 구독자가 다양한 유형의 메시지에 관심을 표현할 수 있도록 하고,

Message Broker(이벤트 버스)를 두어 발행인과 구독자 사이를 더욱 확실히 분리할 수 있는 더욱 복잡한 패턴이다.


주로 미들웨어 시스템에서 많이 사용된다.

 

Observer 패턴은 Observer와 Subject가 서로를 인지하지만 Pub-Sub 패턴의 경우 서로를 전혀 몰라도 상관없다. 

그래서 Observer 패턴의 경우 Subject에 Observer를 등록하고 Subject가 직접 Observer에 직접 알려주어야 한다.

 

Pub-Sub 패턴의 경우 Publisher가 Subscriber의 위치나 존재를 알 필요없이 Message Queue와 같은 Broker 역할을 하는 이벤트 버스에 메시지를 던져 놓기만 하면 된다. 마찬가지로 Subscriber 역시 Publisher의 위치나 존재를 알 필요없이 Broker의 상황을 모니터링하다가 원하는 토픽의 메시지를 받고 작업하면 된다.

따라서 Observer 패턴에 비해 Pub-Sub 패턴이 더 낮은 결합도를 보인다.
  

Publisher와 Subscriber가 서로의 존재를 알 필요가 없기 때문에 당연히 소스코드 역시 겹치거나 의존할 일이 없다.  

만약 결합도가 높다면 의도했거나, 잘못된 코드일 가능성이크다.

그리고 Observer 패턴은 대부분 동기(synchronous) 방식으로 동작하는 반면,

Pub-Sub 패턴은 대부분 비동기(asynchronous) 방식으로 동작한다. Pub-Sub 패턴은 Broker로 Message Queue를 많이 사용하기 때문이다.

 

 

낮은 결합도의 힘

Pub-Sub에 비해 높은 결합도를 가진 Observer 패턴이지만 이는 상대적일 뿐 Observer 패턴도 낮은 결합도를 지향하는 디자인 패턴이다.

 

낮은 결합도의 장점

  • Subject가 Observer에 대해 알고 있는 유일한 것은 Observer가 특정 인터페이스를 구현한다는 것 뿐이다.
    Observer의 구체적인 클래스, Observer가 수행하는 작업 또는 그에 대한 다른 정보를 알 필요가 없다.

  • 언제든지 새로운 Observer를 추가할 수 있다.
    주체가 의존하는 유일한 것은 Observer 인터페이스를 구현하는 객체 리스트이므로 원할 때마다 새로운 Observer를 추가할 수 있다.
    런타임에 Observer를 추가할 수 있고 언제든지 제거할 수도 있다.

  • 새로운 유형의 Observer를 추가하기 위해서 Subject를 수정할 필요가 없다.
    주제는 상관없이 Observer 인터페이스를 구현하는 모든 객체에 알림을 전달한다.

  • Subject나 Observer를 서로 독립적으로 재사용할 수 있다.
  • Subject나 Observer의 변경 사항은 다른 클래스에 영향을 끼치지 않는다.

 

 

옵저버 패턴을 적용한 기상 관측 애플리케이션 다이어그램

  • Subject의 구현체인 WeatherData는 observerList를 가지고 있다.
  • Observer의 구현체인 ThirdPartyDisplay, CurrentConditionsDisplay, StatisticsDisplay, ForecastDisplay는 자신의 상태를 update하는 메서드를 가지고 있다.
  • Subject의 값이 변경되면 Subject를 구독하는 observer들에게 알림(notifyObservers)을 전송한다.

 

Subject의 구현체인 WeatherData 객체

public class WeatherData implements Subject {

    private static List<Observer> observerList = new ArrayList<>();
    private float temperature;
    private float humidity;
    private float pressure;

    @Override
    public void registerObserver(Observer o) {
        observerList.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        observerList.remove(o);
    }

    @Override
    public void notifyObservers() {
        observerList.forEach(o -> o.update(temperature, humidity, pressure));
    }

    public void getMeasurements() {
        
    }

    public void setMeasurements(float temp, float humidity, float pressure) {
        this.temperature = temp;
        this.humidity = humidity;
        this.pressure = pressure;
    }
}
  • Observer 추가, 삭제, 알림 기능을 메서드로 가지고 있다.

 

 

구현이 어렵지 않고 이해하기도 쉬운 패턴이라고 생각된다.

하지만 낮은 결합도를 지향하는 패턴인 만큼 Kafka의 Pub-Sub 구조라던지, 모바일에서 다양한 Listener 기본 패턴으로 활용되는 모습을 보인다. 

 

 

Java는 Observable 클래스(Subject)와 Observer 인터페이스를 제공했다.
하지만 Java9 이후로 이들은 Deprecated 되었는데 대부분의 사람들이 자체적으로 Observer Pattern 을 구현하는 것이 더 쉽다고 느꼈기 때문에 Observer/Observable 클래스를 사용하지 않게 되었다.

 

'Lang > Java' 카테고리의 다른 글

[Java] 가비지 컬렉션(GC, Garbage Collection) 기초  (4) 2022.11.12
전략 패턴 (Strategy Pattern)  (3) 2022.10.04
[Java] Lambda 특징과 활용  (1) 2022.10.03
함수형 프로그래밍과 Java #1  (6) 2022.09.08
[디자인 패턴] 싱글톤 패턴 (Creational)  (0) 2022.01.10
    'Lang/Java' 카테고리의 다른 글
    • [Java] 가비지 컬렉션(GC, Garbage Collection) 기초
    • 전략 패턴 (Strategy Pattern)
    • [Java] Lambda 특징과 활용
    • 함수형 프로그래밍과 Java #1

    티스토리툴바