중재자 패턴 (Mediator Pattern)
Gof Design Pattern2014. 2. 4. 11:33
Mediator Pattern - 중재자 패턴
- 모든 클래스간의 복잡한 로직(상호작용)을 캡슐화하여 하나의 클래스에 위임하여 처리하는 패턴
- M:N의 관계에서 M:1의 관계로 복잡도를 떨어뜨려 유지 보수 및 재사용의 확장성에 유리하다
- 하나의 클래스가 떠맡아 처리해야 하므로 God(신) 클래스가 될 수 있으므로 주의해야한다
- 비슷한 패턴으로 파사드 패턴 (Facade Pattern)과 옵저버 패턴 (Observer Pattern)이 있다.
샘플 코드)
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 93 94 95 96 97 98 99 100 | #include <list> #include <typeinfo> #if _UNICODE typedef wstring tstring; #else typedef string tstring; #endif //------------------------------------------------------------------ // Mediator 인터페이스 class Colleague; // 전방 선언 class Mediator { public: virtual void AddColleague(Colleague* colleague) = 0; virtual void Mediate(const TCHAR* message, Colleague* sender) = 0; }; //------------------------------------------------------------------ // Colleague 인터페이스 class Colleague { public: Colleague(Mediator* m) : pMediator(m) { pMediator->AddColleague(this); } public: void SendMessages(const TCHAR* str) { pMediator->Mediate(str, this); cout << "Message: " << str << ", Sent by: " << GetName() << endl; } void ReceiveMessages(const TCHAR* str) { cout << "Message: " << str << ", Recv by: " << GetName() << endl; } virtual const TCHAR* GetName() = 0; protected: Mediator* pMediator; }; //------------------------------------------------------------------ // ConcreteColleague1 상속 클래스 class ConcreteColleague1 : public Colleague { public: ConcreteColleague1(Mediator* m) : Colleague(m) {} const TCHAR* GetName() { return typeid(this).name(); } }; //------------------------------------------------------------------ // ConcreteColleague2 상속 클래스 class ConcreteColleague2 : public Colleague { public: ConcreteColleague2(Mediator* m) : Colleague(m) {} const TCHAR* GetName() { return typeid(this).name(); } }; //------------------------------------------------------------------ // ConcreteMediator 상속 클래스 class ConcreteMediator : public Mediator { public: void AddColleague(Colleague* colleague) { mList.push_back(colleague); } void Mediate(const TCHAR* message, Colleague* sender) { for (Colleague* object : mList) { if (object != sender) object->ReceiveMessages(message); } } private: list<Colleague*> mList; }; //------------------------------------------------------------------ // Main int _tmain(int argc, _TCHAR* argv[]) { ConcreteMediator mConcreteMediator; ConcreteColleague1 mConcreteColleague1(&mConcreteMediator); ConcreteColleague2 mConcreteColleague2(&mConcreteMediator); mConcreteColleague1.SendMessages("First Message..."); mConcreteColleague2.SendMessages("Second Message...."); return 0; } |
예제를 통한 중재자 패턴(Mediator Pattern) 알아보기
예제) 중재자 패턴을 활용한 채팅 예제
채팅 중재자 클래스를 만들고 유저클래스들을 리스트 컨테이너에서 통합 관리한다. 유저가 메시지 전송을 하게 되면 중재자 클래스에서 자신을 제외한 등록된 모든 유저들에게 메시지를 전송한다.
예제 코드)
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 93 94 95 96 97 98 99 100 101 102 | #include <list> #if _UNICODE typedef wstring tstring; #else typedef string tstring; #endif //------------------------------------------------------------------ // Mediator 인터페이스 class Colleague; // 전방 선언 class Mediator { public: virtual void AppendUser(Colleague* colleague) = 0; virtual void RemoveUser(Colleague* colleague) = 0; virtual void sendMessage(const TCHAR* message, Colleague* sender) = 0; }; //------------------------------------------------------------------ // Colleague 인터페이스 class Colleague { public: Colleague(Mediator* m, const TCHAR* name) : pMediator(m), mName(name) {} public: virtual void SendMessages(const TCHAR* str) = 0; virtual void ReceiveMessages(const TCHAR* str) = 0; protected: Mediator* pMediator; tstring mName; }; //------------------------------------------------------------------ // User 상속 클래스 class User : public Colleague { public: User(Mediator* m, const TCHAR* name) : Colleague(m, name) {} public: void SendMessages(const TCHAR* str) override { cout << mName << " send : " << str << endl; pMediator->sendMessage(str, this); } void ReceiveMessages(const TCHAR* str) override { cout << mName << " recv : " << str << endl; } }; //------------------------------------------------------------------ // ChatMediator 상속 클래스 class ChatMediator : public Mediator { public: void AppendUser(Colleague* colleague) override { mList.push_back(colleague); } void RemoveUser(Colleague* colleague) override { mList.remove(colleague); } void sendMessage(const TCHAR* message, Colleague* sender) { for (Colleague* object : mList) { if (object != sender) object->ReceiveMessages(message); } } private: list<Colleague*> mList; }; //------------------------------------------------------------------ // Main int _tmain(int argc, _TCHAR* argv[]) { ChatMediator mChatMediator; User mUser1(&mChatMediator, "홍길동"); User mUser2(&mChatMediator, "나이스"); User mUser3(&mChatMediator, "디자인"); mChatMediator.AppendUser(&mUser1); mChatMediator.AppendUser(&mUser2); mChatMediator.AppendUser(&mUser3); mUser1.SendMessages("안녕하세요. 홍길동입니다!"); return 0; } |
예제 결과)
'Gof Design Pattern' 카테고리의 다른 글
해석자 패턴 (Interpreter Pattern) (0) | 2014.02.08 |
---|---|
방문자 패턴 (Visitor Pattern) (0) | 2014.02.04 |
반복자 패턴 (Iterator Pattern) (0) | 2014.02.04 |
책임 연쇄 패턴 (Chain of Responsibility) (0) | 2014.02.03 |
커멘트 패턴 (Command Pattern) (2) | 2014.02.03 |