Gof Design Pattern
옵저버 패턴 (Observer Pattern)
copynull
2014. 2. 1. 06:48
Observer Pattern - 옵저버 패턴
- 한 객체의 상태가 바뀌면 그 객체에 이존하는 다른 객체들 모두에게 연락이 가고 자동으로 내용이 갱신되는 패턴
- 1 : N(다) 의 의존성으로 정의한다
- 일방적 통지 (Broadcast) 방식의 패턴
샘플 코드)
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
//------------------------------------------------------------------
// Observer 인터페이스
class Observer
{
public:
virtual void update() = 0;
};
//------------------------------------------------------------------
// ConcreteObserver 상속 클래스
class ConcreteObserver : public Observer
{
public:
void update() override { cout << this << " : update" << endl; }
};
//------------------------------------------------------------------
// Subject 인터페이스 (옵저버들 관리 및 통지)
class Subject
{
public:
void attach(Observer* o) { mList.AddTail(o); }
void detach(Observer* o) { mList.RemoveAt(mList.Find(o)); }
protected:
void notify()
{
POSITION pos = mList.GetHeadPosition();
while (pos != NULL)
mList.GetNext(pos)->update();
}
public:
virtual void change() = 0;
private:
CAtlList<Observer*> mList;
};
//------------------------------------------------------------------
// ConcreteSubject 상속 클래스
class ConcreteSubject : public Subject
{
public:
void change() override { notify(); }
};
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
Subject* pSubject = new ConcreteSubject;
Observer* pObserver1 = new ConcreteObserver;
Observer* pObserver2 = new ConcreteObserver;
Observer* pObserver3 = new ConcreteObserver;
pSubject->attach(pObserver1);
pSubject->attach(pObserver2);
pSubject->attach(pObserver3);
pSubject->change();
pSubject->detach(pObserver1);
pSubject->detach(pObserver2);
pSubject->detach(pObserver3);
pSubject->change();
delete pSubject;
delete pObserver1;
delete pObserver2;
delete pObserver3;
return 0;
}
|
예제를 통한 옵저버 패턴(Observer Pattern) 알아보기
예제) 방송사 -> 시청자 관계를 통한 예제
방송사와 옵저버(시청자)와의 관계를 예를 들었습니다. 방송사는 시청자들을 하나의 컨테이너(리스트)에서 관리하고 시청등록자들에게 방송을 송출하는 부분을 맡고 있고, 옵저버 - 시청자쪽에서는 방송사에서 오는 방송을 그대로 방송시청하도록 1 : N 의 관계로 옵저버 패턴을 설계하였습니다.
예제 코드)
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#include <atlcoll.h>
#if _UNICODE
typedef wstring tstring;
#else
typedef string tstring;
#endif
//------------------------------------------------------------------
// Observer 인터페이스
class 옵저버_인터페이스
{
public:
virtual void 방송시청(const TCHAR* news) = 0;
virtual const TCHAR* 이름() const = 0;
};
//------------------------------------------------------------------
// ConcreteObserver 상속 클래스
class 시청자 : public 옵저버_인터페이스
{
public:
시청자(const TCHAR* name) : mName(name) {}
public:
void 방송시청(const TCHAR* news) override { cout << mName << " : " << news << endl; }
const TCHAR* 이름() const { return mName.c_str(); }
private:
tstring mName;
};
//------------------------------------------------------------------
// Subject 인터페이스 (옵저버들 관리 및 통지)
class 방송사_인터페이스
{
public:
void 방송시청등록(옵저버_인터페이스* o) { mList.AddTail(o); cout << "방송 신청 : " << o->이름() << endl; }
void 방송시청해제(옵저버_인터페이스* o) { mList.RemoveAt(mList.Find(o)); cout << "방송 해지 : " << o->이름() << endl; }
protected:
void 송출(const TCHAR* news)
{
POSITION pos = mList.GetHeadPosition();
while (pos != NULL)
mList.GetNext(pos)->방송시청(news);
}
public:
virtual void 뉴스(const TCHAR* news) = 0;
private:
CAtlList<옵저버_인터페이스*> mList;
};
//------------------------------------------------------------------
// ConcreteSubject 상속 클래스
class 코리아방송 : public 방송사_인터페이스
{
public:
void 뉴스(const TCHAR* news) override { 송출(news); }
};
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
방송사_인터페이스* pSubject = new 코리아방송;
옵저버_인터페이스* pObserver1 = new 시청자("홍길동");
옵저버_인터페이스* pObserver2 = new 시청자("태평양");
옵저버_인터페이스* pObserver3 = new 시청자("비둘기");
pSubject->방송시청등록(pObserver1);
pSubject->방송시청등록(pObserver2);
pSubject->방송시청등록(pObserver3);
pSubject->뉴스("날씨를 말씀드리겠습니다.");
pSubject->방송시청해제(pObserver1);
pSubject->방송시청해제(pObserver2);
pSubject->뉴스("뉴스 속보입니다.");
delete pSubject;
delete pObserver1;
delete pObserver2;
delete pObserver3;
return 0;
}
|
예제 결과)
헤드 퍼스트 디자인 패턴:14가지 GoF 필살 패턴! - 프로그래밍 언어 | 쿠팡
쿠팡에서 헤드 퍼스트 디자인 패턴:14가지 GoF 필살 패턴! 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 프로그래밍 언어 제품도 바로 쿠팡에서 확인할 수 있습니다.
www.coupang.com
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."