2012-07-23 3 views
0

필자의 시나리오에서는 Message 클래스를 통해 통신하는 Component A와 Component B가 있습니다.공통 클래스를 구성 요소 간의 비 공통 함수와 공유하는 방법은 무엇입니까?

class MessageA: public Message { 
    void prepare() { 
    ... 
    } 
    void parse() { 
    ... 
    } 
    void handle() { 
    componentA->executeFunctionABC(); // componentA is a global pointer 
    } 
}; 

구성 요소 A가 MessageA 컴파일

구성 요소 B는 다음과 같습니다

내 메시지 클래스는 예를 들어, 모든 메시지는 메시지 클래스의 서브 클래스입니다이

class Message { 
    virtual void prepare(); 
    virtual void parse(); 
    virtual void handle(); 
}; 

처럼 보인다 MessageA로 컴파일

이렇게하면 컴포넌트 A가 Component B에 메세지를 송신하려면, MessageA 오브젝트를 인스턴스화 해 prepare() 해 송신합니다. Component B가 소켓을 통해 메시지를 수신하면이를 구문 분석()하고 handle()합니다.

이제 내 문제는 handle() 함수에 있습니다. 메시지의 수신자 만 handle() 함수를 호출합니다. handle() 함수의 구현은 수신 컴포넌트의 함수를 포함하는 특정 루틴을 실행해야합니다.

void handle() { 
#ifdef COMPILE_FOR_COMPONENT_A 
componentA->executeFunctionABC(); 
#endif 
} 

을하지만 추한 외모 :

지금과 같이 사전 처리기 사용하여이 문제를 해결할 수 있습니다. 이 작업을 올바르게 수행 할 수있는 디자인 패턴이 있는지 궁금합니다.

답변

0

컴포넌트가 공통 인터페이스를 구현하는 경우, 당신은 handle 방법으로 구성 요소를 전달할 수 있습니다 : 구성 요소가 메시지를 수신

class Component { 
    virtual void executeFunctionABC() = 0; 
    virtual void executeFunctionDEF() = 0; 
} 

class MessageA : public Message { 
    void handle(Component *c) { 
    c->executeFunctionABC(); 
    } 
} 

을, 그것을 부를 것이다 :

message->handle(this); 

을 또한,에서 귀하의 설명, prepareparse은 주로 메시지를 생성/복원하는 데 사용되는 것으로 보이므로 팩토리 메서드 (고정 메서드 인 Message 또는 별도의 MessageFactory 클래스) 대신 Message 클래스의 가상 메서드를 사용하십시오.


편집 :는 다른 방법으로, 각 구성 요소에 대한 별도의 handle 방법을 필요로 visitor pattern을 사용할 수 있습니다 : 당신은 매우 다른 기능을 가진 몇 가지 구성 요소가있는 경우

class MessageA : public Message { 
    void handle(ComponentA *c) { 
    c->executeFunctionABC(); 
    } 

    void handle(ComponentB *c) { 
    ... 
    } 
} 

이 잘 작동합니다. 인터페이스 접근 방식은 유사한 기능을 가진 구성 요소가있는 경우 잘 작동합니다.


편집 2 : 완전히 구성 요소를 분리하려면 이전의 두 솔루션의 하이브리드 사용할 수 있습니다

class MessageHandler { 
    virtual void handle(MessageA *msg) = 0; 
    virtual void handle(MessageB *msg) = 0; 
} 

class MessageA : public Message { 
    void handle(MessageHandler *handler) { 
    handler->handle(this); 
    } 
} 

class ComponentA : public MessageHandler { 
    void handle(MessageA *msg) { 
    executeFunctionABC(); 
    } 
} 

당신은 여전히 ​​구성 요소에 대한 인터페이스 결국, 그러나 만 메시지가있는만큼 많은 방법을 사용하십시오. 이것은 효과적으로 전 처리기 지시문이 달성하는 것입니다.

+0

하지만 하위 클래스 중 하나에서 호출 될 모든 함수를 나열하는 Component 기본 클래스가 필요합니까? – Jeremy

+0

@ Jeremy : 귀하의 의견은 귀하의 구성 요소가 서로 매우 다른 것을 제안합니다. 다른 솔루션에 대한 편집을 참조하십시오. – casablanca

+0

두 번째 솔루션은 4 가지 구성 요소로만 구성됩니다. 한 가지 질문은 메시지 A로 구성 요소 A를 컴파일 할 때 ComponentB.o를 링크해야한다는 것입니다. 맞습니까? 전처리 방법을 사용하면 구성 요소를 완전히 분리 할 수 ​​있습니다. – Jeremy

0

메시지를 처리, 구문 분석 및 준비와 같은 메시지의 작업과 분리 할 수 ​​있습니까?

MessageHandler, MessageParser 및 MessagePreparer의 관점에서 생각해보십시오. 메시지 데이터에 액세스하기 위해 사용할 수있는 일반적인 Message 인터페이스의 부분은 무엇입니까? 무엇이 달라질 것인가?

이것이 작동하면 구성 요소 A에는 MessageA_Preparer 및 MessageB_Handler 및 _Parser가 필요합니다. 구성 요소 B에는 MessageB_Preparer 및 MessageB_Handler 및 _Parser가 필요합니다.

+0

각 메시지는 다른 개인 변수를 데이터로 전달하며 매우 다른 작성자, 구문 분석기 및 처리기가 필요합니다. 그래서 prepare(), parse() 및 handle() 메서드를 특정 메시지에 속하게하고 싶습니다. – Jeremy

+0

그럼 기본 클래스의 목적은 무엇입니까 메시지 – Arkadiy

+0

기본 클래스는 각 메시지가 prepare(), parse() 및 handle()을 구현해야하는지 확인하는 인터페이스입니다. – Jeremy

0

handle() 함수를 처리 할 때의 기존 문제에 대한 답변이 아니지만 메시지가 prepare(), parse()) 및 handle()? prepare()와 receiver 클래스 (parse()를 처리해야 함)를 처리해야하는 송신자 클래스가 있어야하고 handle()을 구현하는 방식에 따라 어쩌면 그렇게 느낄 것입니다.

Message 클래스가 메시지 만 포함하면 발신자 및 수신자 클래스가 다른 기능을 처리하는 것이 더 좋지 않을까요?

관련 문제