GoF 저작 에서 언급 되 지 않 은 디자인 모델 (4): Double Dispatch

11224 단어 Dispatch
우 리 는 먼저 말 그대로 그것 을 이해 합 시다. 직관 적 으로 말 하면 두 번 의 dispatch 를 말 합 니 다.여기 dispatch 가 가리 키 는 게 뭐 죠?예 를 들 어:
   class Event
{
public:
virtual void PrintName()
{
cout
<<" "<<endl;
}
}

class KeyEvent:public Event
{
public:
virtual void PrintName()
{
cout
<<" "<<endl;
}
}

class ClickEvent:public Event
{
public:
virtual void PrintName()
{
cout
<<" "<<endl;
}
}

다 태 성 은 동태 적 이 고 호출 된 방법 은 대상 의 진정한 유형 에 의 해 확정 되 며 이 과정 을 dispatch 라 고 부른다.예 를 들 어 C + + 에서 모든 대상 에 가상 함수 표 가 있 습 니 다. 기본 클래스 의 유형 으로 하위 클래스 대상 을 참조 할 때 가상 함수 포인터 가 가리 키 는 것 은 하위 클래스 의 가상 함수 표 입 니 다. 호출 된 가상 함 수 는 모두 하위 클래스 의 버 전 입 니 다. 그래서 다음 코드 는 '나 는 버튼 이벤트' 입 니 다. 이것 은 dispatch 의 과정 이 라 고 할 수 있 습 니 다.즉, 대상 유형 에 따라 어떤 함 수 를 호출 하 는 과정 을 동적 으로 확정 하 는 것 이다.
   Event* pEvent = new KeyEvent();
pEvent
->PrintName();

 dispatch 는 언제 두 번 사용 하나 요?계속 내 려 다 보기:
   class EventRecorder
{
public:
virtual void RecordEvent(Event* event)
{
cout
<<" EventRecorder "<< endl;
}

virtual void RecordEvent(KeyEvent* event)
{
cout
<<" EventRecorder "<< endl;
}

virtual void RecordEvent(ClickEvent* event)
{
cout
<<" EventRecorder "<< endl;
}
}

class AdvanceEventRecorder:public EventRecorder
{
public:
virtual void RecordEvent(Event* event)
{
cout
<<" EventRecorder "<< endl;
}

virtual void RecordEvent(KeyEvent* event)
{
cout
<<" EventRecorder "<< endl;
}

virtual void RecordEvent(ClickEvent* event)
{
cout
<<" EventRecorder "<< endl;
}
}

이 두 가지 유형 에는 각각 세 개의 리 셋 함수 가 포함 되 어 있 습 니 다. 다 중 태 는 동적 이 고 함수 리 셋 은 정적 입 니 다. 컴 파일 시기 에 확정 되 었 기 때문에 아래 코드 세 션 의 운행 결 과 는 우리 가 기대 하 는 것 이 아 닙 니 다.
   EventRecorder* pRecorder = new AdvanceEventRecorder();
Event
* pEvent = new KeyEvent();
pRecorder
->RecordEvent(pEvent);

출력 내용: 고급 EventRecorder 를 사용 하여 일반적인 이 벤트 를 기록 합 니 다.
실제로 이 장면 에서 우리 가 원 하 는 것 은 AdvanceEventRecorder:: RecordEvent (KeyEvent * event) 이다.
다음은 Double Dispatch 디자인 모델 을 사용 하여 위의 코드 세 션 의 목적 을 달성 하고 모든 이벤트 대상 에 아래 의 함 수 를 추가 합 니 다.
   virtual void RecordEvent(EventRecorder* recorder)
{
recorder
->RecordEvent(this);
}

다음 코드 세 션 을 출력 합 니 다: 고급 EventRecorder 를 사용 하여 버튼 이 벤트 를 기록 합 니 다.
   EventRecorder* pRecorder = new AdvanceEventRecorder();
Event
* pEvent = new KeyEvent();
pEvent
->RecordEvent(pRecorder);

1 차 dispatch 는 KeyEvent 의 RecordEvent (EventRecorder * recorder) 를 정확하게 찾 았 고, 2 차 dispatch 는 AdvanceEventRecorder 의 RecordEvent (KeyEvent * event) 를 찾 았 음 을 알 수 있다.   Visitor 모드 는 Double Dispatch 에 대한 응용 이 며 충돌 검출 알고리즘 에서 도 자주 사용 된다.

좋은 웹페이지 즐겨찾기