[[TableOfContents]] = Mediator = == Intent == MediatorPatternì€ ê°ì²´ë“¤ì˜ ì–´ëŠ ì§‘í•©ë“¤ì´ interaction하는 ë°©ë²•ì„ encapsulate하는 ê°ì²´ë¥¼ ì •ì˜í•œë‹¤. Mediator는 ê°ì²´ë“¤ì„ 서로ì—게 명시ì 으로 조회하는 ê²ƒì„ ë§‰ìŒìœ¼ë¡œì„œ loose couplingì„ ì´‰ì§„í•˜ë©°, 그래서 Mediator는 여러분ì—게 ê°ì²´ë“¤ì˜ interactionsë“¤ì´ ë…립ì 으로 다양하게 해준다. == Motivation == Object-Oriented ë””ìžì¸ì€ ê°ì²´ë“¤ 사ì´ì˜ 행위 ë¶„ì‚°ì„ ìž¥ë ¤í•œë‹¤. 그런 ë¶„ì‚°ì€ ê°ì²´ë“¤ 사ì´ì— ë§Žì€ ì—°ê´€ì„ ì§€ë‹Œ ê°ì²´ 구조로 ë‚˜íƒ€ë‚ ìˆ˜ 있다. ìµœì•…ì˜ ê²½ìš°ì—는 ëª¨ë“ ê°ì²´ê°€ ê²°êµ ëª¨ë“ ë‹¤ë¥¸ ê°ì²´ë“¤ì„ 알게 ëœë‹¤. ë¹„ë¡ í•˜ë‚˜ì˜ ì‹œìŠ¤í…œì— ë§Žì€ ê°ì²´ë“¤ì´ 참여하는 ê²ƒì´ ì¼ë°˜ì 으로 ìž¬ì‚¬ìš©ì„±ì„ ê°•í™”í• ì§€ë¼ë„ interconnectionsì´ ëŠ˜ì–´ë‚˜ëŠ” ê²ƒì€ ìž¬ì‚¬ìš©ì„±ì„ ê°ì†Œì‹œí‚¤ë ¤ëŠ” ê²½í–¥ì´ ìžˆë‹¤. 너무나 ë§Žì€ ê°ì²´ê°„ì˜ ìƒí˜¸ ì—°ê²°ë“¤ì€ ê°ì²´ë“¤ì˜ ë…ë¦½ì„±ì„ ë–¨ì–´ëœ¨ë¦´ 수 있다. - 그런 ì‹œìŠ¤í…œì€ ë§ˆì¹˜ ì™„ì „ížˆ 통ì¼ëœ 것 ê°™ì´ í–‰ë™í•œë‹¤. 게다가 í•˜ë‚˜ì˜ ì‹œìŠ¤í…œì— ë§Žì€ ê°ì²´ë“¤ì´ 참여하는 ê²ƒì€ ì–´ë–¤ ì˜ë¯¸ìžˆëŠ” 방법으로 ì‹œìŠ¤í…œì˜ í–‰ìœ„ë¥¼ 바꾸는 ê²ƒì„ ì–´ë µê²Œ 한다. 왜ëƒí•˜ë©´, 행위는 ë§Žì€ ê°ì²´ë“¤ 사ì´ë¡œ 분산ë˜ì–´ 졌기 때문ì´ë‹¤. ê²°ë¡ ì 으로 ë‹¹ì‹ ì€ ì•„ë§ˆ 그런 ì‹œìŠ¤í…œì˜ í–‰ìœ„ë¥¼ customize하기 위해서 ìˆ˜ë§Žì€ subclassë“¤ì„ ì •ì˜í•´ì•¼ í• ê²ƒì´ë‹¤. ì˜ˆë¡œì¨ ì–´ë–¤ GUIìƒì—ì„œ 다ì´ì–¼ë¡œê·¸ ë°•ìŠ¤ì˜ êµ¬í˜„ì„ ê³ ë ¤í•´ë³´ìž. í•˜ë‚˜ì˜ ë‹¤ì´ì–¼ë¡œê·¸ 박스는 ìž‘ì€ ë„구들(버튼, 메뉴, ìž…ë ¥ í•„ë“œ)ì˜ ëª¨ìŒì„ 표현하는 í•˜ë‚˜ì˜ ìœˆë„우를 사용한다. http://zeropage.org/~reset/zb/data/fontc047.gif 대게 다ì´ì–¼ë¡œê·¸ì˜ ë„구들 사ì´ì—는 ì–´ë–¤ dependencyë“¤ì´ ì¡´ìž¬í•œë‹¤. 예를 들면, ì–´ë–¤ ë²„íŠ¼ì€ ì–´ë–¤ ìž…ë ¥ 필드가 비어있ì„때는 비활성화 ë˜ì–´ìžˆëŠ”다. list boxë¼ ë¶ˆë¦¬ëŠ” ì„ íƒ ëª©ë¡ì—ì„œ ê°ì²´ë¥¼ ì„ íƒí•˜ëŠ” ê²ƒì€ ìž…ë ¥í•„ë“œì˜ ë‚´ìš©ì„ ë°”ê¿€ 것ì´ë‹¤. 바꿔ë§í•˜ë©´, ìž…ë ¥í•„ë“œì— ë¬¸ìžë¥¼ 타ì´í•‘하는 ê²ƒì€ ìžë™ì 으로 리스트 박스ì—ì„œ 하나ì´ìƒì˜ 대ì‘대는 ìž…ë ¥ì„ ì„ íƒí•˜ëŠ” 것ì´ë‹¤. 한번 í…스트가 ìž…ë ¥ í•„ë“œì— ë‚˜íƒ€ë‚˜ë©´, 다른 ë²„íŠ¼ë“¤ì€ ì•„ë§ˆ 활성화 ë 것ì´ë‹¤. 그래서 사용ìžê°€ í…스트로 ì–´ë–¤ ì¼ì„ 하게 í•˜ê²Œí• ê²ƒì´ë‹¤. 예를 들ìžë©´, ê´€ë ¨ìžˆëŠ” ê²ƒì„ ì‚ì œí•˜ê±°ë‚˜ 변경하거나 하는 ë”°ìœ„ì˜ ì¼ì„ í• ìˆ˜ ìžˆì„ ê²ƒì´ë‹¤. 다른 다ì´ì–¼ë¡œê·¸ ë°•ìŠ¤ë“¤ì€ ë„구들 사ì´ì—ì„œ 다른 dependencyë“¤ì„ ì§€ë‹ ê²ƒì´ë‹¤. 그래서 심지어 다ì´ì–¼ë¡œê·¸ë“¤ì´ ë˜‘ê°™ì€ ì¢…ë¥˜ì˜ ë„êµ¬ë“¤ì„ ì§€ë‹Œë‹¤ 하ë”ë¼ë„, 단순히 ì´ì „ì˜ ë„구 í´ëž˜ìŠ¤ë“¤ì„ 재사용 í• ìˆ˜ëŠ” 없다. dialog-specific dependencyë“¤ì„ ë°˜ì˜í•˜ê¸° 위해서 customizeë˜ì–´ì ¸ì•¼ 한다. subclassingì— ì˜í•´ì„œ 개별ì 으로 ë„êµ¬ë“¤ì„ Customize하는 ê²ƒì€ ì§€ë£¨í• ê²ƒì´ë‹¤. 왜ëƒí•˜ë©´ ë§Žì€ í´ëž˜ìŠ¤ë“¤ì´ ê·¸ë ‡ê²Œ ë˜ì–´ì•¼ 하기 때문ì´ë‹¤. ë³„ê°œì˜ mediator ê°ì²´ì—ì„œ ì§‘ë‹¨ì˜ í–‰ìœ„ë¡œ encapsulate하는 ê²ƒì— ì˜í•´ì„œ ì´ëŸ° ë¬¸ì œë¥¼ í”¼í• ìˆ˜ 있다. í•˜ë‚˜ì˜ mediator는 ê°ì²´ë“¤ 그룹 ë‚´ì˜ ìƒí˜¸ìž‘ìš©ë“¤ì„ ì œì–´í•˜ê³ ì¡°ì •í• ì±…ìž„ì´ ìžˆë‹¤. ê·¸ mediator는 ê·¸ë£¹ë‚´ì˜ ê°ì²´ë“¤ì´ 다른 ê°ì²´ë“¤ê³¼ 명시ì 으로 조회하는 ê²ƒì„ ë§‰ëŠ” 중간ìžë¡œì„œì˜ ì—í• ì„ í•œë‹¤. 그런 ê°ì²´ë“¤ì€ 단지 mediator만 ì•Œê³ ìžˆê³ , ê³ ë¡œ interconnectionì˜ ìˆ˜ëŠ” 줄어 들게 ëœë‹¤. 예를 들면, FontDialogDirector는 다ì´ì–¼ë¡œê·¸ ë°•ìŠ¤ì˜ ë„구들 사ì´ì˜ mediatorì¼ ìˆ˜ 있다. FontDialogDirectorê°ì²´ëŠ” 다ì´ì–¼ë¡œê·¸ ë„êµ¬ë“¤ì„ ì•Œê³ ê·¸ë“¤ì˜ interactionì„ ì¡°ì •í•œë‹¤. ê·¸ê²ƒì€ ë„구들 사ì´ì˜ communicationì—ì„œ hub와 ê°™ì€ ì—í• ì„ í•œë‹¤. http://zeropage.org/~reset/zb/data/media033.gif ë‹¤ìŒ interaction diagramì€ ê°ì²´ë“¤ì´ ë¦¬ìŠ¤íŠ¸ë°•ìŠ¤ì˜ ì„ íƒì—ì„œ 변화를 다루기 위해 협ë™í•˜ëŠ” ë°©ë²•ì„ ë¬˜ì‚¬í•˜ê³ ìžˆë‹¤. http://zeropage.org/~reset/zb/data/media031.gif Here's the succession of events by which a list box's selection passes to an entry field. 여기서는 list boxì—ì„œì˜ ì„ íƒì´ entry field ë¡œ ì „ë‹¬ë˜ê³ 있는 ì´ë²¤íŠ¸ë“¤ì˜ íë¦„ì´ ìžˆë‹¤. 1. 리스트 박스가 ê·¸ê²ƒì˜ directorì—게 ê·¸ê²ƒì´ ë³€í–ˆë‹¤ê³ ë§í•œë‹¤. 2. director는 리스트 박스로 부터 ì„ íƒì„ 얻는다. 3. director는 ìž…ë ¥ 필드로 ì„ íƒì„ 넘긴다. 4. ì´ì œ ìž…ë ¥ 필드는 ì–´ë–¤ 문ìžë¥¼ í¬í•¨í•œë‹¤. director는 í–‰ë™(글씨를 굵게 하거나 기울ì´ê²Œ 하는 ë”°ìœ„ì˜ í–‰ë™)ì˜ ì´ˆê¸°í™”ë¥¼ 위해 ë²„íŠ¼ì„ í™œì„±í™” 한다. directorê°€ 리스트 박스와 ìž…ë ¥ í•„ë“œ 사ì´ì˜ ì¡°ì •í•˜ëŠ” ë°©ë²•ì„ ìš”ì•½í•˜ìž. ë„êµ¬ë“¤ì€ ì„œë¡œ 단지 ê°„ì ‘ì 으로 directorì„ í†µí•´ì„œ í†µì‹ í•œë‹¤. ê·¸ë“¤ì€ ì„œë¡œì— ëŒ€í•´ì„œ 몰ë¼ì•¼ 하며, 그들 모ë‘는 director를 알아야 한다. 게다가 행위는 í•œ í´ëž˜ìŠ¤ì— 지ì—í™” ë˜ì–´ì§€ê¸° ë•Œë¬¸ì— í–‰ìœ„ëŠ” í´ëž˜ìŠ¤ë¥¼ 확장하거나 êµì²´í•¨ìœ¼ë¡œì¨ 변하거나 바꿔질 수 있다. FontDialogDirector 추ìƒí™”ê°€ í´ëž˜ìŠ¤ library를 통하하는 ë°©ë²•ì€ ë‹¤ìŒê³¼ 같다. http://zeropage.org/~reset/zb/data/media034.gif DialogDirect는 다ì´ì–¼ë¡œê·¸ì˜ ì „ì²´ 행위를 ì •ì˜í•œ ì¶”ìƒ í´ëž˜ìŠ¤ì´ë‹¤. clientë“¤ì€ í™”ë©´ì— ë‹¤ì´ì–¼ë¡œê·¸ë¥¼ 나타내기 위해서 ShowDialog ì—°ì‚°ìžë¥¼ 호출한다. CreateWidgets는 다ì´ì–¼ë¡œê·¸ ë„êµ¬ë“¤ì„ ë§Œë“¤ê¸° 위한 ì¶”ìƒ ì—°ì‚°ìžì´ë‹¤. WidgetChanged는 ë˜ ë‹¤ë¥¸ ì¶”ìƒ ì—°ì‚°ìžì´ë©°, ë„êµ¬ë“¤ì€ directorì—게 ê·¸ë“¤ì´ ë³€í–ˆë‹¤ëŠ” ê²ƒì„ ì•Œë ¤ì£¼ê¸° 위해서 ì´ë¥¼ 호출한다. DialogDirector subclassë“¤ì€ CreateWidgetsì„ ì ì ˆí•œ ë„êµ¬ë“¤ì„ ë§Œë“¤ê¸° 위해서 overrideí•˜ê³ ê·¸ë¦¬ê³ ê·¸ë“¤ì€ WidgetChanged를 변화를 다루기 위해서 override한다. == Applicability == MediatorPatternì€ ì´ëŸ´ ë•Œ 사용한다. * ì–´ë–¤ ê°ì²´ë“¤ì˜ ì§‘í•©ì´ ìž˜ ì •ì˜ë˜ì—ˆì§€ë§Œ, 복잡한 방법으로 í†µì‹ í• ë•Œ. interconnectionì˜ ê²°ê³¼ëŠ” 구조화ë˜ì§€ ëª»í•˜ê³ ì´í•´ë¥¼ ì–´ë µê²Œ 한다. * ì–´ë–¤ ê°ì²´ë¥¼ 재사용하는 ê²ƒì´ ê·¸ê²ƒì´ ë§Žì€ ë‹¤ë¥¸ ê°ì²´ë“¤ê³¼ ê´€ë ¨ì´ ìžˆê³ í†µì‹ ì„ í•˜ê¸° ë•Œë¬¸ì— ì–´ë ¤ìš¸ ë•Œ. * ëª‡ëª‡ì˜ í´ëž˜ìŠ¤ë“¤ 사ì´ì— 분산ë˜ì–´ì§„ í•˜ë‚˜ì˜ í–‰ìœ„ê°€ ë§Žì€ subclassing하는 ìž‘ì—… ì—†ì´ customizeë˜ì–´ì ¸ì•¼ í• ë•Œ. == Structure == http://zeropage.org/~reset/zb/data/mediator.gif ì „í˜•ì ì¸ ê°ì²´ 구조는 ì´ë ‡ê²Œ ë³´ì¼ ê²ƒì´ë‹¤: http://zeropage.org/~reset/zb/data/media030.gif == Participants == * Mediator(DialogDirector) Colleague ê°ì²´ë“¤ê³¼ í†µì‹ ì„ ìœ„í•´ì„œ ì¸í„°íŽ˜ì´ìŠ¤ë¥¼ ì •ì˜í•œë‹¤. * ConcreteMediator(FontDialogDirector) Colleague ê°ì²´ë“¤ì„ ì¡°ì •í•¨ìœ¼ë¡œì¨ ì—½í•© 행위를 구현한다. ìžì‹ ì˜ colleagueë“¤ì„ ì•Œê³ ê´€ë¦¬í•œë‹¤. * Colleague classes(listBox, Entry Field) ê°ê°ì˜ colleague class는 ìžì‹ ì˜ Mediator ê°ì²´ë¥¼ 안다. ê°ê°€ì˜ colleague 는 ìžì‹ ì´ ë‹¤ë¥¸ colleague와 í†µì‹ í• ë•Œë§ˆë‹¤ ìžì‹ ì˜ mediator와 í†µì‹ í•œë‹¤. == Collaborations == Colleagueë“¤ì€ Mediator ê°ì²´ì—게 ìš”ì²ì„ ë³´ë‚´ê³ ë°›ëŠ”ë‹¤. Mediator는 ì ì ˆí•œ colleagueì—게 ìš”ì²ì„ ë³´ëƒ„ìœ¼ë¡œì¨ í˜‘ë™ í–‰ìœ„ë¥¼ 구현한다. == Consequences == Mediator Patternì€ ë‹¤ìŒê³¼ ê°™ì€ ìž¥ì ê³¼ 단ì ì„ ì§€ë‹Œë‹¤. 1. MediatorPatternì€ subclassingì„ ì œí•œí•œë‹¤. mediator는 다시ë§í•´ ëª‡ëª‡ê°œì˜ ê°ì²´ë“¤ 사ì´ì— 분산ë˜ì–´ì§ˆ 행위를 집중한다. ì´ëŸ° 행위를 바꾸는 ê²ƒì€ ë‹¨ì§€ Mediator를 subclassing하기만 하면 ëœë‹¤. Colleague í´ëž˜ìŠ¤ë“¤ì€ 재사용ë˜ì–´ì§ˆ 수 있다. 2. MediatorPatternì€ colleagueë“¤ì„ ë–¼ì–´ë†“ëŠ”ë‹¤. Mediator는 colleague들 사ì´ì—ì„œ loose couplingì„ ì´‰ì§„í•œë‹¤. colleagued와 Mediator를 개별ì 으로 다양하게 í• ìˆ˜ ìžˆê³ , 재사용 í• ìˆ˜ 있다. 3. MediatorPatternì€ ê°ì²´ protocolsì„ ë‹¨ìˆœí™” 시킨다. Mediator는 다대다 ìƒí˜¸ê´€ê³„를 Mediator와 colleague들 사ì´ì˜ ì¼ëŒ€ë‹¤ 관계로 바꾸어 놓는다. ì¼ëŒ€ë‹¤ 관계는 ì´í•´, 관리, í™•ìž¥í•˜ëŠ”ë° ë” ì‰½ë‹¤. 4. MediatorPatternì€ ê°ì²´ê°€ 협ë™í•˜ëŠ” ë°©ë²•ì„ ì¶”ìƒí™” 시킨다. Mediation를 ë…립ì ì¸ ê°œë…으로 ë§Œë“¤ê³ í•˜ë‚˜ì˜ ê°ì²´ì— 캡ìŠí™”하는 ê²ƒì€ ì—¬ëŸ¬ë¶„ìœ¼ë¡œ 하여금 ê°ì²´ì˜ 행위는 ì œì³ë‘ê³ ê·¸ interactionì— ì§‘ì¤‘í•˜ê²Œ 해준다. ì´ëŠ” ê°ì²´ê°€ 시스템 ë‚´ì—ì„œ 어떻게 interact하는 ë°©ë²•ì„ ëª…í™•ížˆ í•˜ëŠ”ë° ë„ì›€ì„ ì¤€ë‹¤. 5. MediatorPatternì€ ì œì–´ë¥¼ 집중화한다. Mediator는 interactionì˜ ë³µìž¡ë„를 mediatorì˜ ë³µìž¡ë„와 맞바꿨다. Mediatorê°€ protocolë“¤ì„ encapsulate했기 ë•Œë¬¸ì— colleagueê°ì²´ë“¤ 보다 ë” ë³µìž¡í•˜ê²Œ ë˜ì–´ì§ˆ 수 있다. ì´ê²ƒì´ mediator를 관리가 ì–´ë ¤ìš´ monolith 형태를 뛰게 만들 수 있다. == Implementation == ë‹¤ìŒ êµ¬í˜„ê³¼ ê´€ë ¨ëœ issueë“¤ì€ MediatorPatternê³¼ ê´€ë ¨ì´ ìžˆë‹¤. 1. ì¶”ìƒ Mediator í´ëž˜ìŠ¤ ìƒëžµí•˜ê¸°. ì¶”ìƒ Mediator í´ëž˜ìŠ¤ë¥¼ ì„ ì–¸í• í•„ìš”ê°€ 없는 경우는 colleagueë“¤ì´ ë‹¨ì§€ í•˜ë‚˜ì˜ mediator와만 ìž‘ì—…ì„ í• ë•Œì´ë‹¤. Mediatorí´ëž˜ìŠ¤ê°€ ì œê³µí•˜ëŠ” 추ìƒì ì¸ couplingì€ colleagueë“¤ì´ ë‹¤ë¥¸ mediator subclass들과 ìž‘ë™í•™ê²Œ 해주며 ë°˜ëŒ€ì˜ ê²½ìš°ë„ ê·¸ë ‡ë‹¤. 2. Colleague-Mediator communication. colleagueë“¤ì€ ê·¸ë“¤ì˜ mediator와 í¥ë¯¸ë¡œìš´ ì´ë²¤íŠ¸ê°€ ë°œìƒí–ˆì„ ë•Œ, í†µì‹ ì„ í•´ì•¼í•œë‹¤. 한가지 ë°©ë²•ì€ mediator를 Observer로서(ObserverPatternì„ ì´ìš©í•´ì„œ) 구현하는 것ì´ë‹¤. colleague ê°ì²´ë“¤ì€ Subject들로서 ìž‘ë™í•˜ê³ , ìžì‹ ì˜ ìƒíƒœê°€ ë³€í–ˆì„ ë•Œ, 지시를 Mediatorì—게 ì „ë‹¬í•œë‹¤. Mediator는 ë³€í™”ì˜ íš¨ê³¼ë¥¼ 다른 colleague들ì—게 ì „ë‹¬í•˜ëŠ” ë°˜ì‘ì„ í•œë‹¤. ë˜ ë‹¤ë¥¸ ë°©ë²•ì€ colleagueë“¤ì´ ë³´ë‹¤ ë” ì§ì ‘으로 communicationí• ìˆ˜ 있ë„ë¡ íŠ¹ë³„í•œ interface를 mediatorì—게 심는 것ì´ë‹¤. 윈ë„ìš°ìš© Smalltalk/Vê°€ 대표ì ì¸ í˜•íƒœì´ë‹¤. mediator와 í†µì‹ ì„ í•˜ê³ ìž í• ë•Œ, ìžì‹ ì„ argumentë¡œ 넘겨서 mediatorê°€ senderê°€ 누구ì¸ì§€ ì‹ë³„하게 한다. Sample Code는 ì´ì™€ ê°™ì€ ë°©ë²•ì„ ì‚¬ìš©í•˜ê³ ìžˆê³ , Smalltalk/Vì˜ êµ¬í˜„ì€ Known Usesì—ì„œ 다루기로 í•˜ê² ë‹¤. == Sample Code == 우리는 DialogDirector를 Motivationì—ì„œ ë³´ì•˜ë˜ ê²ƒì²˜ëŸ¼ font dialog를 구현하기 위해서 ì‚¬ìš©í• ê²ƒì´ë‹¤. ì¶”ìƒ í´ëž˜ìŠ¤ DialogDirector는 directorë“¤ì„ ìœ„í•œ interface를 ì •ì˜ í•˜ê³ ìžˆë‹¤. {{{~cpp class DialogDirector { public: virtual ~DialogDirector(); virtual void ShowDialog(); virtual void WidgetChanged(Widget) = 0; protected: DialogDirector(); virtual void CreateWidgets() = 0; }; }}} Widget ì€ widgetsë“¤ì„ ìœ„í•œ ì¶”ìƒ ê¸°ì´ˆ í´ëž˜ìŠ¤ì´ë‹¤. í•˜ë‚˜ì˜ widgetì€ ìžì‹ ì˜ director를 ì•Œê³ ìžˆë‹¤. {{{~cpp class Widget { public: Widget(DialogDirector*); virtual void Changed(); virtual void handleMouse(MouseEvent& event); //... private: DialogDirector* _director; }; }}} changed 는 directorì˜ WidgetChanged ì—°ì‚°ì„ í˜¸ì¶œí•œë‹¤. Widgetë“¤ì€ ìžì‹ ì˜ directorì˜ WidgetChanged í˜¸ì¶œì„ ì˜ë¯¸ìžˆëŠ” ì´ë²¤íŠ¸ë¥¼ ì•Œì ¸ì£¼ê¸° 위해서 사용한다. {{{~cpp void Widget::Changed() { _director->WidgetChanged(this); } }}} DialogDirectorì˜ subclassë“¤ì€ ì ì ˆí•œ widgetìž‘ë™í•˜ê¸° 위해서 WidgetChanged를 overrideí•´ì„œ ì´ìš©í•œë‹¤. widgetì€ ìžì‹ ì˜ referece를 WidgetChangedì— argument로서 넘겨줌으로서 ì–´ë–¤ widgetì˜ ìƒíƒœê°€ 바뀌었는지를 directorë¡œ 하여금 알게해준다. DialogDirectorì˜ subclassë“¤ì€ CreateWidget 순수 ì¶”ìƒ ì—°ì‚°ìžë¥¼ 다ì´ì–¼ë¡œê·¸ì— widgetë“¤ì„ ë§Œë“¤ê¸° 위해 ìž¬ì •ì˜í•œë‹¤. ListBox, EntryField, Buttonì€ íŠ¹í™”ëœ ì‚¬ìš©ìž ì¸í„°íŽ˜ì´ìŠ¤ 요소를 위한 DialogDirectorì˜ subclass들ì´ë‹¤. ListBox는 현재 ì„ íƒì„ 위해서 GetSelectionì—°ì‚°ìžë¥¼ ì œê³µí•œë‹¤. ê·¸ë¦¬ê³ EntryFieldì˜ SetText ì—°ì‚°ìžëŠ” 새로운 textë¡œ field를 채운다. {{{~cpp class ListBox:public Widget { public: ListBox(DialogDirector*); virtual const char* GetSelection(); virtual void SetList(List* listItems); virtual void HandMouse(MouseEvent& event); //.. }; class EntryField:public Widget { pblic: EntryField(DialogDirector*); virtual void SetText(const char* text); virtual const char* GetText(); virtual void handleMouse(MouseEvent& event); //... }; }}} Buttonì€ ê·¸ê²ƒì´ ëˆŒëŸ¬ì¡Œì„ ë•Œ, Changed를 호출하는 단순한 widgetì´ë‹¤. ì´ëŠ” HandleMouse를 êµ¬í˜„í•¨ìœ¼ë¡œì¨ ë˜ì–´ì§„다. {{{~cpp class Button : public widget { public: button(DialogDirector*); virtual void SetText(const char* text); virtual void HandleMouse(MouseEvent& event); //... }; void Button::HandleMouse(MouseEvent& event) { //.... Change(); } }}} FontDialogDirector í´ëž˜ìŠ¤ëŠ” 다ì´ì–¼ë¡œê·¸ ë°•ìŠ¤ì˜ widgets사ì´ì— ì¤‘ê°„ì´ ìœ„ì¹˜í•œë‹¤. FontDialogDirector는 DialogDirectorì˜ í•˜ìœ„ í´ëž˜ìŠ¤ì´ë‹¤. {{{~cpp class FontDialogDirector:public DialogDirector { public: FontDialogDirector(); virtual ~FontDialogDirector(); virtual void WidgetChanged(Widget*); protected: virtual void CreateWidgets(); private Button* _ok; Buton* _cancel; ListBox* _fontList; entryField* _fontName; }; }}} FontDialogDirector는 ê·¸ê²ƒì´ display하는 widgetì„ ì¶”ì 한다. ê·¸ê²ƒì€ widgetë“¤ì„ ë§Œë“¤ê¸° 위해서 CreateWidgetì„ ìž¬ì •ì˜í•˜ê³ ê·¸ê²ƒì˜ referenceë¡œ ê·¸ê²ƒë“¤ì„ ì´ˆê¸°í™”í•œë‹¤. {{{~cpp void FontDialogDirector::CreateWidgets() { _ok = new Button(this); _cnacel = new Button(this); _fontList = new ListBox(this); _fontName = new EntryField(this); // fill the listBox white the available font names // assemble the widgets in the dialog }; }}} WidgetChanged는 widgetë“¤ì´ ì„œë¡œ ì ì ˆí•˜ê²Œ ë™ìž‘하는 ê²ƒì„ í™•ì‹ í•˜ê²Œ 한다. {{{~cpp void FontDialogDirector::WidgetChanged( Widget* theChangedWidget ) { if(theChangedWidget ==_fontList) { _fontName->GetTet(_fontList->GetSelection()); } else if (theChangedWidget == _ok) { //apply font chnage and dismiss dialog //... } else if (theChangedWidget ==_cancel) { //dismiss dialog } } }}} WidgetChangedì˜ ë³µìž¡ì„±ì€ ê·¸ë§Œí¼ ë‹¤ì´ì–¼ë¡œê·¸ ë³µìž¡ì„±ì„ ë†’ì¸ë‹¤. ë¬¼ë¡ í° ë‹¤ì´ì–¼ë¡œê·¸ëŠ” 다른 ì´ìœ ë¡œ ì¸í•´ì„œ 바람ì§í•˜ì§€ 못하지만, mediator ë³µìž¡ì„±ì€ ë‹¤ë¥¸ application들ì—ì„œ íŒ¨í„´ì˜ ìž‡ì ì„ ì™„í™”ì‹œí‚¨ë‹¤. == Known Uses == ET++[WGM88]와 THINK C class library[Sm93b]는 다ì´ì–¼ë¡œê·¸ì—ì„œ widget들 사ì´ì— mediator로서 director와 ìœ ì‚¬í•œ ê°ì²´ë¥¼ 사용한다. 윈ë„ìš°ìš© Smalltalk/Vì˜ application구조는 mediator êµ¬ì¡°ì— ê°€ë°˜ì„ ë‘ê³ ìžˆë‹¤.[LaL94] 그런 환경ì—ì„œ applicationì€ ìœˆë„우를 paneë“¤ì˜ ëª¨ìŒìœ¼ë¡œ êµ¬ì„±í•˜ê³ ìžˆë‹¤. library는 ëª‡ëª‡ì˜ ì´ë¯¸ ì •ì˜ëœ paneë“¤ì„ ê°€ì§€ê³ ìžˆë‹¤. 예를 들ìžë©´ TextPane, ListBox, Buttonë“±ë“±ì´ í¬í•¨ëœë‹¤. ì´ëŸ¬í•œ paneë“¤ì€ subclassingì—†ì´ ì´ìš©ë 수 있다. Application 개발ìžëŠ” 단지 inter-pane coordinationí• ì±…ìž„ì´ ìžˆëŠ” ViewManager만 subclassingí• ìˆ˜ 있다. ViewManage는 Mediatorì´ê³ ê°ê°ì˜ paneë“¤ì€ ìžì‹ ì˜ owner로서 단지 ìžì‹ ì˜ ViewManager를 ì•Œê³ ìžˆë‹¤. paneë“¤ì€ ì§ì ‘ì 으로 서로 조회하지 않는다. ë‹¤ìŒ object diagramì€ run-timeì— applicationì˜ snapshotì„ ë³´ì—¬ì£¼ê³ ìžˆë‹¤. http://zeropage.org/~reset/zb/data/media032.gif SmallTalk/V는 Pane-ViewManager í†µì‹ ì„ ìœ„í•´ event ê¸°ë²•ì„ ì‚¬ìš©í•˜ê³ ìžˆë‹¤. ì–´ë–¤ paneì€ ì–´ë–¤ ì •ë³´ë¥¼ mediatorë¡œ 부터 얻기 ì›í•˜ê±°ë‚˜ ì–´ë–¤ ì˜ë¯¸ìžˆëŠ” ì¼ì´ ë°œìƒí•´ì„œ ì´ë¥¼ mediatorì—게 ì•Œë ¤ì£¼ê¸° 위해서 event를 ìƒì„±í•œë‹¤. í•˜ë‚˜ì˜ event는 ê·¸ event를 ì‹ë³„하는 symbolì„ ì •ì˜í•œë‹¤. ê·¸ event를 다루기 위해서 ViewManager는 paneì— method selector를 등ë¡í•œë‹¤. ì´ selector는 eventì˜ handlerì´ë‹¤. ì´ê²ƒì€ eventê°€ ë°œìƒí•œ 때면 ì–¸ì œë“ ì§€ 수행ë 것ì´ë‹¤. ë‹¤ìŒ ì½”ë“œ ì¸ìš©ì€ ListBoxê°€ ViewManager subclass ë‚´ì—ì„œ 만들어지는 방법과 #select event를 위해 ViewManagerê°€ event handler를 등ë¡í•˜ëŠ” ë°©ë²•ì„ ë³´ì—¬ì£¼ê³ ìžˆë‹¤. {{{~cpp self addSubpane: (ListPane new paneName: 'myListPane'; owner: self; when: #select perform: #listSlet:). }}} MediatorPatternì˜ ë˜ë‹¤ë¥¸ applicationì€ coordinating complex updatesì— ìžˆë‹¤. í•˜ë‚˜ì˜ ì˜ˆëŠ” Observer로서 언급ë˜ì–´ì§€ëŠ” ChangeManager classì´ë‹¤. ChangeManager는 중복 update를 피하기 위해서 subjectsê³¼ observersì¤‘ê°„ì— ìœ„ì¹˜í•œë‹¤. ê°ì²´ê°€ ë³€í• ë•Œ, ChangeManagerì—게 알린다. 그래서 ChangeManager는 ê°ì²´ì˜ dependecy를 알리는 것으로 update를 ì¡°ì •í•œë‹¤. ìœ ì‚¬í•œ applicationì€ Unidraw drawing frameworkì—ì„œ ë‚˜íƒ€ë‚˜ê³ [VL90] connectors사ì´ì— 연결성 ì œì•½ë“¤ì„ ì 용하는 CSolverë¼ ë¶ˆë¦¬ëŠ” class를 사용한다. 그래픽 편집기ì—ì„œ ê°ì²´ë“¤ì€ 다른 방법으로 서로 다른 ê°ì²´ë“¤ì„ 짜집는 것으로 ë³´ì¼ ìˆ˜ 있다. connectorë“¤ì€ ì—°ê²°ì„±ì´ ìžë™ì 으로 관리ë˜ëŠ” 그림 편집기나 회로 설계 시스템과 ê°™ì€ application들ì—ì„œ ìœ ìš©í•˜ë‹¤. CSolver는 ê°ì²´ë“¤ 사ì´ì— mediatorì´ë‹¤. ê·¸ê²ƒì€ ì—°ê²°ì œì•½ì„ í•´ê²°í•˜ê³ , connectorë“¤ì˜ ìœ„ì¹˜ë¥¼ ê·¸ê²ƒë“¤ì„ ë°˜ì˜í•˜ê¸° 위해서 update한다. == Related Patterns == FacadePattern(185)ì€ ë³´ë‹¤ 편리한 ì¸í„°íŽ˜ì´ìŠ¤ë¥¼ ì œê³µí•˜ê³ ìž subsystemì˜ ê°ì²´ë“¤ì„ 추ìƒí™”시킨 Mediator와 다르다. ê·¸ê²ƒì˜ protocolì€ ê°„ì ‘ì ì´ë‹¤. 다시 ë§í•˜ë©´ Facade ê°ì²´ë“¤ì€ subsystemì˜ ìš”ì²ë“¤ì„ 만들지만 ë°˜ëŒ€ì˜ ê²½ìš°ëŠ” ê·¸ë ‡ì§€ 못하다. 대조ì 으로 Mediator는 colleagueë“¤ì´ ì œê³µí•˜ì§€ 못하거나 í• ìˆ˜ 없는 협ë™ì ì¸ í–‰ìœ„ë¥¼ 가능하게 해준다. 그래서 ê·¸ protocolì€ multidirectional하다. 기본ì 으로 FacadePatternì€ í´ëž˜ìŠ¤ ì§‘ë‹¨ì´ ìžˆê³ , ê·¸ í´ëž˜ìŠ¤ ì§‘ë‹¨ì„ ì‚¬ìš©í•˜ëŠ” 외부 í´ëž˜ìŠ¤ì˜ 입장ì—ì„œ 필요한 패턴ì´ê³ , MediatorPatternì€ í´ëž˜ìŠ¤ ì§‘ë‹¨ì´ ìžˆê³ , ê·¸ í´ëž˜ìŠ¤ 집단 내부ì—ì„œ 서로를 사용하기 위한 패턴ì´ë‹¤. 예컨대, Seminar:ElevatorSimulation ì— ì—¬ëŸ¬ê°€ì§€ ë°°ìš°(ì—˜ë ˆë² ì´í„°, 사람, 층, ...)ë“¤ì´ ì¡´ìž¬í• ê²½ìš°, ì‚¬ëžŒì€ ì¸µì„ ì°¸ì¡°, ì‚¬ìš©í•˜ê³ , ì¸µì€ ë‹¤ì‹œ ê°–ê³ ìžˆëŠ” ì‚¬ëžŒì„ ì°¸ì¡°í•˜ê³ , ì—˜ë ˆë² ì´í„°ëŠ” ì‚¬ëžŒì„ ì°¸ì¡°, ì‚¬ìš©í•˜ê³ í•˜ëŠ” ì‹ìœ¼ë¡œ 복잡한 (순환) ì˜ì¡´ê´€ê³„ê°€ 존재한다. ì´ëŸ´ ë•Œ MediatorPatternì„ ì“°ê²Œë˜ë©´ ì´ ë³µìž¡í•œ ì˜ì¡´ê³ 리를 ëŠì„ 수 있다. colleagueë“¤ì€ observer(293) patternì„ ì´ìš©í•˜ëŠ” Mediator와 í†µì‹ í• ìˆ˜ 있다. ---- Facade 와 Mediator 를 ê°€ë” í˜¼ë™í–ˆì—ˆëŠ”ë°. í¬ë¡ì´í˜• ê°ì‚¬ê°ì‚¬ìš”~~ --["1002"] ---- ["패턴분류"]