학습목표 l 옵서버패턴 l 상태패턴 l 커맨드패턴 l 실습문제 2

Similar documents
쉽게 풀어쓴 C 프로그래밍

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

gnu-lee-oop-kor-lec06-3-chap7

JAVA PROGRAMMING 실습 08.다형성

Microsoft PowerPoint - Java7.pptx

C# Programming Guide - Types

JAVA PROGRAMMING 실습 05. 객체의 활용

fundamentalOfCommandPattern_calmglow_pattern_jstorm_1.0_f…

강의10

DocsPin_Korean.pages

설계란 무엇인가?

PowerPoint 프레젠테이션

Microsoft Word - FunctionCall

01-OOPConcepts(2).PDF

Microsoft PowerPoint - [2009] 02.pptx

금오공대 컴퓨터공학전공 강의자료

PowerPoint 프레젠테이션

PowerPoint Presentation

q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2

<C0DAB7E120C7D5BABB2E687770>

<C0CCBCBCBFB52DC1A4B4EBBFF82DBCAEBBE7B3EDB9AE2D D382E687770>

PowerPoint 프레젠테이션

Something that can be seen, touched or otherwise sensed

Microsoft PowerPoint - C++ 5 .pptx

No Slide Title

Microsoft PowerPoint - chap06-2pointer.ppt

thesis

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

소프트웨어공학 Tutorial #2: StarUML Eun Man Choi

Network seminar.key

1. 객체의생성과대입 int 형변수 : 선언과동시에초기화하는방법 (C++) int a = 3; int a(3); // 기본타입역시클래스와같이처리가능 객체의생성 ( 복습 ) class CPoint private : int x, y; public : CPoint(int a

Microsoft PowerPoint - 04-UDP Programming.ppt

1. auto_ptr 다음프로그램의문제점은무엇인가? void func(void) int *p = new int; cout << " 양수입력 : "; cin >> *p; if (*p <= 0) cout << " 양수를입력해야합니다 " << endl; return; 동적할

다른 JSP 페이지호출 forward() 메서드 - 하나의 JSP 페이지실행이끝나고다른 JSP 페이지를호출할때사용한다. 예 ) <% RequestDispatcher dispatcher = request.getrequestdispatcher(" 실행할페이지.jsp");

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

PowerPoint Template

쉽게 풀어쓴 C 프로그래밍

17장 클래스와 메소드

PowerPoint Presentation

chap10.PDF

제목

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

Microsoft PowerPoint - 11_DesignPatterns(2010).ppt [호환 모드]

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

슬라이드 1

API 매뉴얼

Microsoft PowerPoint - Chapter 6.ppt

유니티 변수-함수.key

쉽게 풀어쓴 C 프로그래밍

1. What is AX1 AX1 Program은 WIZnet 사의 Hardwired TCP/IP Chip인 iinchip 들의성능평가및 Test를위해제작된 Windows 기반의 PC Program이다. AX1은 Internet을통해 iinchip Evaluation

Lab 3. 실습문제 (Single linked list)_해답.hwp

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

Interstage5 SOAP서비스 설정 가이드

Chapter #01 Subject

비트와바이트 비트와바이트 비트 (Bit) : 2진수값하나 (0 또는 1) 를저장할수있는최소메모리공간 1비트 2비트 3비트... n비트 2^1 = 2개 2^2 = 4개 2^3 = 8개... 2^n 개 1 바이트는 8 비트 2 2

Eclipse 와 Firefox 를이용한 Javascript 개발 발표자 : 문경대 11 년 10 월 26 일수요일

슬라이드 1

Microsoft PowerPoint 장강의노트.ppt

1. 클래스와배열 int 형배열선언및초기화 int ary[5] = 1, 2, 3, 4, 5 ; for (int i = 0; i < 5; i++) cout << "ary[" << i << "] = " << ary[i] << endl; 5 장클래스의활용 1

K&R2 Reference Manual 번역본

설계란 무엇인가?

chapter4

13주-14주proc.PDF

슬라이드 1

chap 5: Trees

Chapter 4. LISTS

슬라이드 1

MVVM 패턴의 이해

Microsoft PowerPoint - es-arduino-lecture-03

PowerPoint Presentation

Microsoft PowerPoint - additional01.ppt [호환 모드]

JUNIT 실습및발표

PowerPoint Presentation

6주차.key

Domino Designer Portal Development tools Rational Application Developer WebSphere Portlet Factory Workplace Designer Workplace Forms Designer

API STORE 키발급및 API 사용가이드 Document Information 문서명 : API STORE 언어별 Client 사용가이드작성자 : 작성일 : 업무영역 : 버전 : 1 st Draft. 서브시스템 : 문서번호 : 단계 : Docum

Chapter 4. LISTS

PowerPoint Presentation

(Microsoft PowerPoint - 11_DesignPatterns\(2008\).ppt [\310\243\310\257 \270\360\265\345])


PowerPoint Presentation

어댑터뷰

제11장 프로세스와 쓰레드

API - Notification 메크로를통하여어느특정상황이되었을때 SolidWorks 및보낸경로를통하여알림메시지를보낼수있습니다. 이번기술자료에서는메크로에서이벤트처리기를통하여진행할예정이며, 메크로에서작업을수행하는데유용할것입니다. 알림이벤트핸들러는응용프로그램구현하는데있어

MAX+plus II Getting Started - 무작정따라하기

PowerPoint Template

- 목차 - - ios 개발환경및유의사항. - 플랫폼 ios Project. - Native Controller와플랫폼화면연동. - 플랫폼 Web(js)-Native 간데이터공유. - 플랫폼확장 WN Interface 함수개발. - Network Manager clas

API 매뉴얼

Lab 4. 실습문제 (Circular singly linked list)_해답.hwp

C++ Programming

Connection 8 22 UniSQLConnection / / 9 3 UniSQL OID SET

2 단계 : 추상화 class 오리 { class 청둥오리 extends 오리 { class 물오리 extends 오리 { 청둥오리 mallardduck = new 청둥오리 (); 물오리 redheadduck = new 물오리 (); mallardduck.swim();

final_thesis

rmi_박준용_final.PDF

C++ Programming

DIY 챗봇 - LangCon

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

DataBinding

<4D F736F F F696E74202D2036C0CFC2B05FB0B4C3BCC1F6C7E2C7C1B7CEB1D7B7A1B9D62E707074>

vm-웨어-앞부속

Transcription:

객체지향설계와패턴 Lecture #13: 행위패턴 (2) Eun Man Choi emchoi@dgu.ac.kr

학습목표 l 옵서버패턴 l 상태패턴 l 커맨드패턴 l 실습문제 2

Pattern #16 옵서버패턴 한객체에의하여영향받는객체들을정리하는데사용 l 패턴요약 l 단일객체가영향받는객체집합에대하여같은이름의메소드를호출하여구현 l 관찰대상객체가관찰하는객체가몇개인지어떤클래스인지모름 3

옵서버패턴 : 동기 당신은기업정보입출력프로그램을개발중이다. 이프로그램을이용하여사용자들은 DB 에저장되어있는기업정보 ( 월판매액, 매출증가량, ) 를여러가지형태 ( 도표, 꺾은선그래프, 막대그래프,..) 로볼수있어야한다. 또한관리자들이특정기업정보를갱신한다면해당정보를보여주고있는모든 View 들은변경된정보를다시반영하여보여주어야한다. 기업정보 (Model) 과보여주는화면 (View) 과의관계를어떻게설계할것인가? data 값이변경된다면 view-1, view-2 가변경된값을반영하도록 4

옵서버패턴 : 동기 [ 해결방안 ] l Model(data) 이변경되면이를각 view( 화면 ) 들에게알려줌 Model a:45 b:35 c:20 View-1: PieChart View-2: BarChart 값변동시 Model 은 view-1, view-2 에변동사실을통지함 l Model 은자신의정보변경에대한 notification 을받기를원하는뷰들에대한레퍼런스를가지고있어야한다. Model 에는뷰들을등록하고관리할수있는인터페이스가필요 - Attach(View *): 통지받을 view 등록 - Detach(View *): 통지받을 view 등록해제 - Notify(): 변경발생시등록된 view 들에게통보 5

옵서버패턴 : 동기 [ 해결방안 ] -2 l 정보변경통보를받은뷰들은모델 l 에게서변경된정보를얻어옴 Model a:45 b:35 c:20 GetValues GetValues View-1: PieChart View-2: BarChart l 각뷰들은자신이필요로하는모델에대한레퍼런스를가지고있으며, 모델에게원하는정보를얻어올수있다. 6

옵서버패턴 : 동기 [ 해결방안 ] -3 Notify() 변화발생 7

옵서버패턴 : 동기 [ 해결방안 ] -4 l Model class 도향후확장을고려하여 class hierarchy 로구성 l Observer pattern 에서는통지하는역할을 Subject, 통지받는역할을 Observer 라고얘기함. Subject Observer 8

옵서버패턴 l 의도 l 별칭 l 한객체의상태가변하면관련된다른모든객체들이해당상태변화를알수있도록객체들간의 one-to-many 의존관계를정의한다. l Dependents, Publish-Subscribe l 적용범위 l 시스템의한부분이다른부분에의존적일때, 양자를개별적인객체로만들고 Observer pattern 을적용하면, 독립성과재사용성을높일수있다. l 한객체의상태가변경되면다른객체들도따라변경될필요가있을때, 그리고, 얼마나많은객체들이따라서변경되어야하는지알필요가없을때. l 변경을알리는객체와변경을통지받는객체간의연결강도를줄일때 9

옵서버패턴 l Structure 10

옵서버패턴 l 참여요소 l Subject 통지받을 Observer 객체들을알고있다. Observer 객체들을추가하고삭제하는 interface 를제공한다. Attach(), Detach() l Observer(View) 상태변경통지를받을 interface 를정의한다. - Update() l ConcreteSubject(Model) ConcreteObserver 객체들이필요로하는정보를가지고있다. 정보가변경되면등록된 Observer 객체들에게통보한다. l ConcreteObserver(BarChart, PieChart) 필요한정보를가지고있는 ConcreteSubject 객체를알고있다. 상태변경통지를받으면 ConcreteSubject 객체에게변경된정보를얻어온다. 11

옵서버패턴 l 협동관계 12

옵서버패턴 l 결과 l Subject 객체와 Observer 객체간의 coupling 을줄임 Subject 객체는단지 Observer 객체 list 를가지고있다는정도만알면된다. Subject class 와 Observer class 가서로독립적으로변경및확장될수있다. l Broadcast 통신에도이용가능 Observer 객체들이원하는 subject 객체에등록하지않고, subject 의상태가변화되면전체객체들에게상태변화를 broadcast함 l 예상치못한 updates 발생가능 관찰자객체들 (Observers) 간에는상호존재를인식하지못하기때문에, 한 Subject 객체의상태변화가전체적으로어느정도만큼의 Observer 변화비용이드는지알지못함 13

옵서버패턴 l 구현 l Mapping subjects to their observers Subject 객체가 Observer 객체들을관리하는방식은? The simplest way: Subject 객체가 Observer reference 를포함 Subject 객체가많고 Observer 객체가적다면 Subject 가가지고있을 Observer references 가중복되어메모리낭비가발생한다 ( 대안 : Hash Table). l Observing more than one subject 필요로하는정보의종류에따라, 한 Observer 객체가통지를원하는 Subject 객체를여러개둘수있다. 변경통지가왔을때어떤 Subject 객체에서온통지인지확인은? Update() 함수의인자로통지를보내는 Subject 객체를넘김 l Who triggers the update? 1. Subject 의내부변수값변경시자동으로 Notify() 호출하기 2. Client 에서 Notify() 함수를직접호출하기 14

옵서버패턴 l Dangling references to deleted subjects 특정 Subject 객체가소멸된다면, 이객체를 reference하고있는 Observer 객체들은어떻게할것인가? 소멸되는 Subject 객체에등록된 Observer들에게 Subject가소멸됨을통지해주어야함 l Making sure Subject state is self-consistent before notification Subject 객체의 Notify() 호출되기전에 Subject 객체내부상태값은일관성을유지하여야한다. l Avoiding observer-specific update protocol Subject 객체는단지 Update() 호출을통하여상태변화만알려주고, 실제 Subject 객체의정보를얻어오는작업은 ConcreteObserver 객체들이맡게되면, 속도면에서는조금손해나 Subject-Observer 간의연결강도 (coupling) 은낮아진다 (Pull Model) Subject 객체가상태변화를통지하기위하여 Observer 객체들의 Update() 함수를호출할때변화된값도같이넘겨준다면속도는높일수있으나 Subject-Observer 간의연결강도가높아진다 (Push Model) 15

옵서버패턴 l Specifying modifications of interest explicitly 특정 Observer 객체의경우, Subject 객체의정보들중일부에만관심이있을경우에는? Observer 객체가 Subject 객체의 Attach() 를호출하여자신을등록할때관심이있는세부정보에대한선택도같이넘겨야한다. Subject 객체의내부정보에변경이일어났을때, 해당항목에관련된 Observer 들에게만선택적으로통지한다. l Encapsulating complex update semantics 다수의 Subject 객체와 Observer 객체들간의관계가특별히복잡하고비효율적이라면, 변경통보와변경값반영을전담해주는 ChangeManager 같은별도의객체를둘수있다. 16

옵서버패턴 : 사례 #1 l Sample Code l ClockTimer(ConcreteSubject) 시간정보를가지고있으며시간을보여주는객체에시간변경을알림 l DigitalClock, AnalogClock(ConcreteObserver) ClockTimer에서시간정보를가져와서화면에보여주는역할 Subject Observer ClockTimer DigitalClock AnalogClock 17

옵서버패턴 : 사례 #1 class Subject { public: virtual ~Subject(); virtual void Attach(Observer* o) { _observers->append(o); virtual void Detach(Observer* o) { _observers->remove(o); virtual void Notify() { ListIterator<Observer*> i(_observers); for (i.first();!i.isdone(); i.next()) i.currentitem()->update(this); protected: Subject(); private: List<Observer*> *_observers; ; Iterator 를이용하여등록한모든 Observer 객체들에게변화를알림 class ClockTimer : public Subject { public: ClockTimer(); virtual int GetHour(); // return Hour virtual int GetMinute(); // return Minute virtual int GetSecond(); // return Second void Tick() { // update internal time-keeping state //... Notify(); ; 18 상태변화발생 Notify() 함수호출

옵서버패턴 : 사례 #1 class DigitalClock: public Widget, public Observer { public: DigitalClock(ClockTimer* s) { class AnalogClock : public Widget, public Observer { _subject = s; public: _subject->attach(this); AnalogClock(ClockTimer*); virtual void Update(Subject*); virtual ~DigitalClock() { virtual void Draw(); _subject->detach(this); //... ; virtual void Update(Subject* thechangedsubject) { if (thechangedsubject == _subject) Draw(); virtual void Draw() { // get the new values from the subject int hour = _subject->gethour(); int minute = _subject->getminute(); // etc. // draw the digital clock private: ClockTimer* _subject; ; 19 필요정보를가지고있는객체가변경을통보하였으면다시그림 // Client Code ClockTimer* timer = new ClockTimer; AnalogClock* analogclock = new AnalogClock(timer); DigitalClock* digitalclock = new DigitalClock(timer); timer->tick(); // updates analogclock & digitalclock.

옵서버패턴 : 사례 #1 l 적용사례 l Smalltalk Model/View/Controller(MVC) l ET++, THINK library l InterViews, Andrew Toolkit, Unidraw: user interface part l 관련패턴 l Mediator: Observer pattern 에서변경통보와변경값반영을전담해주는 ChangeManager 같은별도의객체를두는경우, 이객체는 Subject 객체와 Observer 객체들사이의상호작용을조절하는 Mediator 역할을수행한다. l Singleton: ChangeManager 같은경우일반적으로하나의객체만생성하기때문에 Singleton pattern을사용할수있다. 20

옵서버패턴 : 사례 #2(Mutual Fund) Note: HiGrowthMutualFund starts with 3 shares of Awesome, assumes price of 1.0, and has non-awesome holdings totalling 400.0 Note: MedGrowthMutualFund starts with 2 shares of Awesome, assumes price of 1.0, and has non-awesome holdings totalling 300.0 Note: LoGrowthMutualFund starts with 1 shares of Awesome, assumes price of 1.0, and has non-awesome holdings totalling 200.0 Enter 'quit': Any other input to continue. go on Enter the current price of Awesome Inc. in decimal form. 32.1 Value of Lo Growth Mutual Fund changed from 201.0 to 232.1 Value of Med Growth Mutual Fund changed from 302.0 to 364.2 Value of Hi Growth Mutual Fund changed from 403.0 to 496.3 Enter 'quit': Any other input to continue. go on Enter the current price of Awesome Inc. in decimal form. 21.0 Value of Lo Growth Mutual Fund changed from 232.1 to 221.0 Value of Med Growth Mutual Fund changed from 364.2 to 342.0 Value of Hi Growth Mutual Fund changed from 496.3 to 463.0 Enter 'quit': Any other input to continue. 21

Observer Example: Mutual Funds Observable notifyobservers() Observer update( Observable, Object ) Setup MutualFund value numawesomeshares Key: 22 Client Java API Class Developer Class AwesomeInc price LongTermMutualFund. MediumTermMutualFund update( ). HiGrowthMutualFund update( ). update( )

Pattern #17 상태패턴 객체의상태에의하여결정된방법으로객체를동작하게할때사용 l 패턴요약 l 상태객체를따로만들어포함하게하고상태객체에게위임하여동작하게함 23

상태패턴 - 동기 당신은새로운프로젝트의프로그램 reviewer 책임을맡았다. Reviewer 로당신은팀원들이개발한핵심코드를살펴보고, 논리상의문제점이나좋지않은설계구조를지적해주어야한다. 오늘살펴본코드에는, 특정객체가자신의상태에따라다른행동을하기위하여 if 문장을많이사용하였다. 그러다보니, 함수의크기가커지고객체상태가많은경우해당객체의구현이더욱복잡해졌다. 개발자에게조언해줄해결방법은? 함수내에서단순상태변수값으로행동을나누어실행하는코드를어떻게개선할수있을까? 24

상태패턴 - 동기 [ 해결방안 ] l 객체의가능한상태개수만큼 State class 를작성한다. 예 ) Socket 연결을대표하는 TCPConnection class 가가질수있는상태를 Established( 연결 ), Listen( 대기 ), Closed( 끊김 ) 라고가정하면각각 TCPEstablished, TCPListen, TCPClosed class 를만든다. TCPState TCPEstablished TCPClosed TCPListen l 일반적으로 State class 의 interface 는특정상태에따라객체의행위가달라지는함수들을포함한다. TCPConnection ActiveOpen() PassiveOpen() Close() Transmit() GetOption() TCPState ActiveOpen() PassiveOpen() Close() Transmit() 상태에따라다르게동작하는함수들 25

상태패턴 - 동기 l TCPConnection class 와 State class 에자신의상태를변화시킬수있는 ChangeState() 함수를추가한다. TCPConnection ActiveOpen() PassiveOpen() Close() Transmit() GetOption() ChangeState() TCPState ActiveOpen() PassiveOpen() Close() Transmit() ChangeState() l State 객체가 TCPConnection 객체를알수있도록한다. 함수를호출할때인자로 TCPConnection 객체를넘겨주던가, 아니면각 State 객체가생성될때 TCPConnection 객체 reference 를가지든가. à 여기서는전자로 TCPState ActiveOpen(TCPConnection *) PassiveOpen(TCPConnection *) Close(TCPConnection *) Transmit(TCPConnection *, TCPStream *) ChangeState(TCPConnection *, TCPState *) 26

상태패턴 - 동기 l 상태변수대신초기 State 객체를가진다. class TCPConnection { TCPState *_state; ; TCPConnection::TCPConnection() { _state = new TCPClosed(); // 초기상태 l 상태변수값에따라분기되는각행위들을제각기분리하여위에서만든각 State class 에집어넣는다. 27 TCPConnection::Transmit() { if (state==closed) { else if (state==established) { else if ( state== LISTEN) { TCPClosed::Transmit(TCPConnection *t) { TCPEstablished::Transmit(TCPConnection *t) { TCPListen::Transmit(TCPConnection *t) {

상태패턴 - 동기 l 기존객체의상태에의존적인함수는 State 객체로의 delegation 으로구현한다. TCPConnection::Transmit() { if (state==closed) { else if (state==established) { else if ( state== LISTEN) { TCPConnection::Transmit() { _state->transmit(); TCPConnection 객체가가지고있는 State객체 28

상태패턴 - 동기 l TCPConnection 객체의상태변화는내부함수나 State 객체에서만일으킬수있다 (ChangeState() 를 private 으로 ). aclient atcpconnection ChangeState() atcpstate l TCPConnection 객체상태변화예 29 void TCPConnection::ChangeState(TCPState *s) { delete _state; _state = s; void TCPState::ChangeState(TCPConnection *t, TCPState *s) { t->changestate(t, s); void TCPClosed::ActiveOpen(TCPConnection *t) { // do connection operation. ChangeState(t, new TCPEstablished );

상태패턴 - 동기 l State 객체가독자적인정보를가지지않는다면, 객체를여러개가질필요는없음. State 객체는특정객체의행위들을각상태에따라모아놓은것이기때문에단순함수집합으로간주해도됨 Singleton pattern 활용 앞의예에서 Singleton pattern 을사용한모습 void TCPConnection::ChangeState(TCPState *s) { _state = s; void TCPState::ChangeState(TCPConnection *t, TCPState *s) { t->changestate(t, s); void TCPClosed::ActiveOpen(TCPConnection *t) { // do connection operation. ChangeState(t, TCPEstablished::Instance() ); 30

상태패턴 - 동기 l Class diagram 31

상태패턴 l 의도 l 별칭 l 객체의내부상태가변경되었을때그에따라객체의행위도변경되게한다. ( 마치다른 class 의객체가된것처럼 ) l Objects for States l 적용범위 l 객체의행위가해당객체의상태에따라달라질때. l 객체의함수코드가객체의상태에따라큰부분의조건문장으로구성되어있을때 (if 문장, switch 문장 ) 32

상태패턴 l Structure 33

상태패턴 l 참여요소 l l l l 협동 l l l Context(TCPConnection) 현재상태를나타내는 ConcreteState 객체 reference 를가진다. State(TCPState) Context 객체의현재상태에따라다른행위를하는함수들의 interface 를정의한다. ConcreteState(TCPEstablished, TCPClosed, TCPListen) 각 Class 들은 Context 객체의특정상태에따라수행되는행위들을구현 Context 객체는상태의존적인요청에대해서는 ConcreteState 객체에요청을 delegation 한다. Context 객체가 ConcreteState 객체함수를호출할때자신의 reference 를인자로넘길수있다. 일반적으로 Client 가 Context 객체를초기화하는것외에는상태변환에직접적인개입을하지않는다. l Context 객체의상태변화는 Context 나 ConcreteState 객체의작업수행도중에일어난다. 34

상태패턴 l 결과 l It localizes state-specific behavior and partitions behavior for different state State pattern 은특정상태에연관된행위들을하나의객체로만든다. 모든상태의존코드가 State subclass 로존재하기때문에새로운상태를추가하여구현하기가용이하다. 상태조건에따라다중의 If 문장으로구성된복잡한함수를 simple 하게만든다. l It makes state transitions explicit 상태전환이일어나면참조하는객체가바뀐다. l State objects can be shared State subclass 들이개별적내부정보를가지지않는다면그객체들은공유될수있다. 즉, 하나의객체가여러 Context에서사용가능하다. 35

상태패턴 l 구현 l Who defines the state transitions? 상태전환에대한고정된규칙은없다. Context 나 ConcreteState 객체의특정함수내에서필요에따라 Context::ChangeState() 함수를호출하여상태전환할수있다. l A table-based alternative 상태전환표 : 각상태에서가능한입력에따라전환되는상태를기록한표 표를검색해야하므로속도가느림 사람이이해하기어려움 상태전환도중에특정한행동을수행하게만드는것이어려움 l Creating and destroying State objects 각 State 객체를필요할때생성하고, 필요없을때삭제한다. 개별내부정보가없을경우에는 Singleton pattern 을이용하여하나의객체만생성하여사용한다. 36

상태패턴 사례 #1 l Sample Code l Motivation 해결방안에대한프로그램코드 l Classes TCPConnection, TCPState, TCPEstablished, TCPClosed, TCPListen 37 class TCPConnection { public: TCPConnection(); void ActiveOpen(); void PassiveOpen(); void Close(); void Send(); void Transmit(TCPStream *s); void ProcessStream(TCPStream *s); private: friend class TCPState; void ChangeState(TCPState*); private: TCPState* _state; ; TCPConnection::TCPConnection () { _state = TCPClosed::Instance(); void TCPConnection::ChangeState (TCPState* s) { _state = s; void TCPConnection::ActiveOpen () { _state->activeopen(this); void TCPConnection::PassiveOpen () { _state->passiveopen(this); state 객체로요청 delegation void TCPConnection::Close () { _state->close(this); void TCPConnection::Send() { _state->send(this); void TCPConnection::Transmit(TCPStream *s) { _state->transmit(this, s);

상태패턴 : 사례 #1 class TCPState { public: virtual void ActiveOpen(TCPConnection*) { virtual void PassiveOpen(TCPConnection*) { virtual void Close(TCPConnection*) { virtual void Send(TCPConnection *) { virtual void Transmit(TCPConnection*, TCPStream*) { protected: void ChangeState(TCPConnection* t, TCPState* s) { t->changestate(s); ; class TCPEstablished : public TCPState { public: static TCPState* Instance(); 상태에따라서로다르게행동하는함수들 Empty body function 으로 default 함수구현 Established 상태에서만 Transmit() 함수가정보를전송 38 Established 상태에서 Close() 가호출되면대기상태 (Listen) 로변환 virtual void Transmit(TCPConnection* t, TCPStream* o) { t->processstream(o); virtual void Close(TCPConnection* t) { // send FIN, receive ACK of FIN ChangeState(t, TCPListen::Instance()); private: TCPEstablished() { ;

상태패턴 39 class TCPClosed : public TCPState { public: static TCPState* Instance(); void ActiveOpen (TCPConnection* t) { // send SYN, receive SYN, ACK, etc. ChangeState(t, TCPEstablished::Instance()); void PassiveOpen (TCPConnection* t) { ChangeState(t, TCPListen::Instance()); // private: TCPClosed() { //... ; Singleton pattern 사용 Close 상태에서 ActiveOpen() 호출하면 Established 상태로전환 class TCPListen : public TCPState { public: static TCPState* Instance(); void TCPListen::Send (TCPConnection* t) { // send SYN, receive SYN, ACK, etc. ChangeState(t, TCPEstablished::Instance()); // private: TCPListen() { Listen 상태에서 Send() 호출하면 // Established 상태로전환

상태패턴 l 적용사례 l TCP Connection Protocol (Johnson and Zweig) l HotDraw, Unidraw: drawing editor frameworks l Coplien s Envelope-Letter idiom l 관련패턴 l Singletons: State 객체를하나만생성해야될때 Singleton pattern 사용 l Flyweight: 여러종류의 State 객체들을공유해야할때 Flyweight pattern 을활용할수있다. 40

Pattern #18 커멘드패턴 서비스를호출할때융통성을높이려고사용 ( 예, undo 오퍼레이션 ) l 패턴요약 l 오퍼레이션을클래스로정의 41

커멘드패턴 - 동기 PDA s GUI System 개발프로젝트에참여한당신이맡은업무는 window main-menu 부분의설계이다. 각 application은 mainmenu를가지고있고, main-menu의각 menu 들은여러개의 menu-item 을가지고있다. 사용자가특정 menu-item 을선택하면해당 menu-item에연동된기능이수행된다. 당신은어떤식으로설계할것인가? main-menu File menu Open menu: 문서열기기능수행 42

커멘드패턴 - 동기 l Application s menu 모델링 지정된기능수행 파일열기기능호출 - File Open menu-item 선택 - Toolbar 에서 file open icon 선택 - Hotkey(Ctrl-O) 누르기 다양한기능요청방법을지원하기위해서는각요청을하는객체 (menuitem, toolbarbutton, hotkey) 와요청자체를분리하는것이필요 43

커멘드패턴 - 동기 l Application s menu 모델링 -2 l 기능요청 ( 예 : 문서열기 ) 자체를객체화 Command l 기능요청을원하는각객체에해당 Command 객체를연결예 ) File - Open menu-item, Toolbar s open icon, Ctrl-O hotkey l 기능요청을원하는각객체가선택될때연결된 Command 객체실행 command.execute(); 지정된 command 객체실행 44

커멘드패턴 - 동기 [Command class hierarchy] (1) PasteCommand: 현위치에 Clipboard 내용붙여넣기 ; 다른객체 (document) 에요청보내기 (2) OpenCommand: 문서열기 ; 몇개의연산조합으로기능수행. (2) (1) 45

커멘드패턴 - 동기 l [Command class hierarchy -2] (3) MacroCommand: 다른 Command 객체들을연속으로실행 46

커멘드패턴 - 동기 [Undo Mechanism: Commands undo()] - 실행된작업되돌리기 - 각 Command 객체마다자신의작업을되돌릴수있는 Undo() 함수구현 - 지금까지실행된 Command 객체들을모아두고, 이를역순으로 Undo() 호출 47

커멘드패턴 l 의도 l 별칭 l Encapsulate a request as an object l 기능요청을객체화함으로써, 동적으로기능설정을바꾸거나실행된기능들을기록하거나실행된작업들을재복구시킬수있다. l Action, Transaction 48

커멘드패턴 l 적용범위 l MenuItem 객체의경우처럼, 객체에수행되어야할행위 (action) 를동적으로설정할때 l 작업수행을요청한시점과실제작업이수행되어야할시점을다르게할필요가있을때 l Undo 기능을지원하고자할때 l System 의기능수행정도를기록하고싶을때 ; 각 Command 객체들이수행될때마다자신의기록을남김 l 기본적인행위들을조합하여더욱복잡한행위를실행하고자할때 ; MacroCommand 사용 49

커멘드패턴 l Structure 50

커멘드패턴 l Participants l Command ; 연산수행에대한 Interface 정의 - Execute() l ConcreteCommand (OpenCommand, PasteCommand, ) ; 연산수행을위한 Execute() 함수구현 ; Execute() 함수는적절한 Receiver 의함수 ( 들 ) 을호출해서기능수행 l Client (Application) ; ConcreteCommand 객체를생성하고, 해당객체에 Receiver 객체를설정한다. l Invoker (MenuItem) ; Command 객체에게기능수행을요청한다. l Receiver (Document, Application) ; ConcreteCommand 객체들이연산을수행하는데필요한기능들을제공한다. 51

커멘드패턴 l l Collaboration Steps 1. Client 가 ConcreteCommand 객체를생성하고, 해당객체에 Receiver 객체를설정한다. 2. Invoker 객체는적합한 ConcreteCommand 객체의 reference 를가진다. 3. Invoker 객체는자신이가지고있는 ConcreteCommand 객체의 reference 를통하여기능을요청한다. - command->execute() 4. 요청을받은 ConcreteCommand 객체는 Step1. 에서설정된 Receiver 객체의함수를이용하여요청을실행한다. 52

커멘드패턴 1 2 4 3 53

커멘드패턴 l 결과 l 작업수행을요청하는객체와실제작업을수행하는객체를분리시킨다. l 작업요청자체가객체가되기때문에, 다른객체처럼 작업요청 자체를저장하고, 복구하고, 확장할수있다. l 기본적인행위들을조합하여더욱복잡한행위를실행하고자할때 l 기존코드의변경없이새로운 Command 를추가할수있다. 54

커멘드패턴 l 구현 l How intelligent should a command be? Command 는 단순히받은 request 를 Receiver 객체에게전달만하는것 에서부터 주된 Receiver 객체도움없이자신이모든것을구현하는것 까지그범위가다양하다. l Supporting undo and redo? Command 로실행된작업들을복구하려면어떻게? 실행된 Command 객체들을저장한 History List 필요 Motivation -6. Slide 참조. l Using C++ template Execute() 함수에인자가필요없고, undo 기능이필요없다면, ConcreteCommand class 를쉽게만들기위하여 C++ template을이용할수있다. 55

커멘드패턴 사례 #1 C++ template 코드예 Receiver class 를인자로 template <class Receiver> class SimpleCommand : public Command { public: typedef void (Receiver::* Action)(); SimpleCommand(Receiver* r, Action a) : _receiver(r), _action(a) { 56 virtual void Execute() { (_receiver->*_action)(); private: Action _action; Receiver* _receiver; ; class MyClass { public: void Action(); ; Command 객체에 Receiver 객체와함수지정 // Client Code MyClass* receiver = new MyClass; //... Command* acommand = new SimpleCommand<MyClass>(receiver, &MyClass::Action); //... acommand->execute();

커멘드패턴 사례 #1 l Sample Code l Motivation -4, -5. Slide 에나오는 Class diagram 구현 57 class Document { public: Document(const char*); void Open(); void Paste(); ; class Application { public: Application(); void Add(Document*); ; class Command { public: virtual ~Command(); virtual void Execute() = 0; protected: Command(); ; class OpenCommand : public Command { public: OpenCommand(Application* a) { _application = a; virtual void Execute() { const char* name = AskUser(); Receiver 객체인 application 지정 if (name!= 0) { Document* document = new Document(name); _application->add(document); document->open(); protected: virtual const char* AskUser(); private: Application* _application; char* _response; ; application 과 document 객체를이용하여요청구현

커멘드패턴 사례 #1 58 class PasteCommand : public Command { public: PasteCommand(Document* doc) { _document = doc; virtual void Execute() { _document->paste(); private: Document* _document; ; Iterator 을이용하여저장되어있는 Command 객체들의 Execute() 호출 List template 을이용하여 Command 객체들을저장 class MacroCommand : public Command { public: MacroCommand(); virtual ~MacroCommand(); virtual void Add(Command* c) { _cmds->append(c); virtual void Remove(Command* c) { _cmds->remove(c); virtual void Execute() { ListIterator<Command*> i(_cmds); for (i.first();!i.isdone(); i.next()) { Command* c = i.currentitem(); c->execute(); private: List<Command*>* _cmds; ; 수행될 Command 객체들추가및삭제

커멘드패턴 사례 #1 l 사용사례 l MacApp system, THINK class library : Undoable operation l ET++, InterViews, Unidraw system l 관련패턴 l MacroCommand 를구현하는데 Composite pattern 을사용할수있다. l Undo 기능을위해서보관해야될관련객체들의상태정보를표현하기위하여 Memento pattern 을적용할수있다. l Undo 기능을위하여 Command 객체가 History list에복사될때 Prototype pattern 을적용할수있다. 59