티스토리 뷰
observer는 관찰하는 사람, 즉 ‘관찰자’라는 의미다.
옵저버 패턴에서는 관찰 대상의 상태가 변화하면 관찰자에게 알려준다.
옵저버 패턴은 상태 변화에 따른 처리를 기술할 때 효과적이다.
다음 링크는 옵저버 패턴의 예제 코드다.
옵저버 패턴의 등장인물
Subject(관찰 대상자)의 역할 - NumberGenerator
‘관찰되는 대상'을 나타낸다.
Subject 역할은 관찰자인 Observer 역할을 등록하는 메서드와 삭제하는 메서드를 가진다.
또한, ‘현재의 상태를 취득하는' 메서드도 선언되어 있다.
ConcreteSubject(구체적인 관찰 대상자)의 역할 - RandomNumberGenerator
‘관찰되는 대상'을 표현하는 역할을 한다.
상태가 변화하면 그것이 등록되어 있는 Observer 역할에 전달한다.
Observer(관찰자)의 역할 - Observer
Subject 역할로부터 ‘상태가 변했다’라고 전달 받는 역할을 한다.
이를 위한 메서드는 update다.
ConcreteObserver(구체적인 관찰자)의 역할 - DigitObserver, GraphObserver
Observer를 구현하는 역할을 한다.
update 메서드가 호출되면 그 메서드 안에서 Subject 역할의 현재 상태를 취득한다.
교환 가능성
디자인 패턴의 목적 중 하나는 클래스를 재이용 가능한 부품으로 만드는 일이다.
옵저버 패턴에서는 상태를 가지고 있는 ConcreteSubject 역할과 상태변화를 전달 받는 ConcreteObserver 역할이 등장했다.
이 두 가지의 역할을 연결하는 것이 인터페이스(API)인 Subject 역할과 Observer 역할이다.
RandomNumberGenerator 클래스는 자신을 관찰하는 것이 어떤 인스턴스인지 관심이 없다.
그저 observer 필드에 저장되어 있는 인스턴스들이 Observer 인터페이스를 구현하고 있다는 것만 알고 있다.
이 인스턴스들은 addObserver에서 추가된 것이므로 반드시 Observer 인터페이스를 구현하고 있으며 update 메서드를 호출할 수 있다.
DigitObserver 또한 자신이 관찰하는 것이 어떤 인스턴스인지 관심이 없다.
옵저버의 순서
Subject 역할에는 복수의 Observer 역할이 등록되어 있다.
예제 프로그램의 notifyObservers 메서드에서는 먼저 등록한 Observer의 update 메서드가 먼저 호출된다.
일반적으로 ConcreteObserver 역할의 클래스를 설계할 경우에는 update 메서드가 호출되는 순서가 변해도 문제가 일어나지 않도록 해야 한다.
DigitObserver의 update를 호출한 후가 아니라면 GraphObserver의 update가 바르게 동작해야 한다.
원래 각 클래스의 독립성이 보장되면 의존성의 혼란은 별로 발생하지 않는다.
그러나 다음과 같은 상황에서는 주의해야 한다.
Observer의 행위가 Subject에 영향을 미칠 때
일반적인 Observer 패턴에서는 Subject 역할이 다른 클래스로부터 update 메서드의 호출을 요청받는 경우가 있다.
GUI에서는 사용자가 버튼을 눌러 요청하면 update 메서드가 호출되는 경우가 자주 있다.
그런데 Subject 역할이 update 메서드를 호출할 때 Observer 역할이 호출을 요청하는 경우도 있다.
이와 같은 경우 조심해서 설계하지 않으면 메서드 호출이 영원히 계속될 가능성이 있다.
Subject의 상태가 변화 → Observer에게 전달 → Observer가 Subject의 메서드를 호출 → 이것에 의해 Subject의 상태가 변화 → Observer에게 전달 → ...
이것을 방지하기 위해서는 Observer 역할에게 ‘현재 Subject 역할로부터 전달받고 있는 중인지 아닌지'를 나타내는 플래그 변수를 한 개 갖도록 하는 것이 좋다.
관찰보다는 전달 받길 기다린다
observer는 관찰자라는 의미이지만 실제로 Observer는 능동적으로 관찰하는 것이 아닌 수동적으로 Subject의 전달을 기다리는 것이다.
그러므로 옵저버 패턴은 Pub/Sub 패턴이라고도 한다.
publish(발행)과 subscribe(구독)라는 표현이 더 적당할 수도 있다.
관련 패턴
- Mediator 패턴
'JAVA > 디자인 패턴' 카테고리의 다른 글
상태(State) 패턴 (0) | 2022.04.18 |
---|---|
메멘토(Memento) 패턴 (0) | 2022.04.03 |
미디에이터(Mediator) 패턴 (0) | 2022.04.02 |
파사드(Facade) 패턴 (0) | 2022.03.31 |
책임 떠넘기기(Chain of Responsibility) 패턴 (0) | 2022.03.30 |
- Total
- Today
- Yesterday
- 클린 코드
- 정규표현식
- kotest
- JPA
- C++
- 객체지향
- 이펙티브 자바
- node.js
- MSA
- Java
- 알고리즘
- 프로그래머스
- BAEKJOON
- Spring Boot
- AWS
- 코테
- 이팩티브 자바
- BOJ
- Spring
- programmers
- 테라폼
- Algorithm
- Effective Java
- Kotlin
- 백준
- 디자인패턴
- kkoon9
- 디자인 패턴
- Olympiad
- 클린 아키텍처
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |