일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- graph
- CS Academy
- BFSDFS
- backtracking
- hashing
- Eulerian circuit
- BST
- Segment Tree
- BOJ
- Eulerian path
- Dag
- Algospot
- dynamic programming
- Shortest path
- flows
- DynamicProgramming
- POJ
- Greedy
- disjoint-set
- bitmask
- Sieve_of_Eratosthenes
- 백준
- scc
- Cycle detecting
- implementation
- Euler circuit
- graph modeling
- mathematics
- GCD
- Euler path
- Today
- Total
그냥 하는 노트와 메모장
옵저버 패턴(Observer pattern) 본문
* 옵저버 패턴(Observer pattern)
[정의] 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 방식으로 의존성을 정의한다.
[그림 : UML(출처: https://en.wikipedia.org/wiki/Observer_pattern)]
옵저버 패턴은 크게 주제(Subject) 클래스와 옵저버(Observer) 클래스로 이루어져 있다. 주제 클래스는 감시 가능한 데이터를 가지고 있고, 이 데이터들을 보고 싶은 클래스를 옵저버 클래스로 둔다.
옵저버 패턴의 핵심은 감시 가능한 데이터의 변경에 대해 "알람"을 받고 싶은 클래스들이 많을 때 활용할 수 있다. 아날로그적으로 비유하자면 신문 배달이나 방송으로 둘 수 있다. 신문을 예시로 더 깊게 들어가보면 신문은 구독을 신청한 사람에게만 전달된다. 신문 배달부는 어디에 배달해야 하는지 "주소"만 알고 있으며 그 주소에 살고 있는 "사람"이 누구인지, 뭘 하는 사람인지 알지도 알 필요도 없다.
[ 그림 : 신문 배달부(출처: https://kr.freeimages.com/premium/paperboy-delivering-the-newspaper-1810864)]
옵저버 패턴은 이 신문 배달처럼 똑같은 방식을 보여준다. 신문사가 곧 주제 클래스, 신문은 감시 가능한 데이터, 구독자는 옵저버 클래스가 되며 주소는 그대로 옵저버 클래스의 객체의 레퍼런스가 된다. 또한 구독자의 정보를 주소말고 알 필요가 없다는 점은 느슨한 결합(Loose coupling) 개념에 부합한다.
※ 느슨한 결합(Loose coupling)은 서로 다른 두 객체가 서로에 대해 상호작용은 하지만 서로에 대해 잘 모른다는 것을 의미한다. 상호작용에 필요한 메소드만을 사용하겠다는 것이다.
[ 표 : 신문과 옵저버의 유사성 ]
주제 클래스는 자신의 데이터를 관찰하고자 하는 옵저버 클래스 컬렉션(Collection)을 가지고 있으며 옵저버 추가 및 제거가 가능하다. 이는 곧 UML에서 주제 클래스와 옵저버 클래스의 집합 관계(Aggregation, 비어있는 다이아)로 확인할 수 있다.
* 알림 방식(Notify methods)
주제 클래스에서 등록된 옵저버들에게 데이터가 변경됐음을 알릴 때 사용할 수 있는 방식은 두 가지가 있다. 두 가지 모두 사용할 수 있으며 장단점을 잘 보며 선택하자
1. Push 방식 - 인자(Parameter) 사용
데이터를 넘겨주는 방식이 주제 클래스에서 직접 넘겨주는 방식이다.
- 장점: 단 번에 데이터들을 인자로 넘겨줌으로써 모든 옵저버들에게 같은 방식으로 알려줄 수 있다.
- 단점: 멤버 변수가 추가되면 옵저버의 인터페이스는 물론, 모든 옵저버 클래스의 소스를 수정해야 한다.
※ 넘겨주는 인자를 클래스로 두어서 그 클래스 안에서 처리한다면 해결할 수 있긴하다.
ex) void update(MyDataClass myDataClass); // MyDataClass에 데이터를 추가 및 삭제
2. Pull 방식 - getter/ setter 메소드 사용
데이터를 얻어오는 방식이 옵저버 클래스에서 주제 클래스의 getter/ setter 메소드를 통해 가져오는 방식이다.
- 장점: 각 옵저버 클래스에서 필요한 데이터만 가져올 수 있다.
- 단점: 주제 클래스에 대한 캡슐화가 깨질 수 있다. 또한 느슨한 결합으로 볼 수 없을 수 있다.
'GoF design pattern' 카테고리의 다른 글
프록시 패턴(Proxy pattern) (0) | 2019.03.09 |
---|