2013-07-01 6 views
0

MessageAMessageB의 두 가지 종류의 메시지가 있습니다. 둘 다 순수 가상 메소드 std::string toString()을 포함한 추상 클래스 IMessage에서 파생되었습니다. 그래서 각 메시지를 기본 클래스에 대한 포인터로 문자열 표현으로 변환 할 수 있습니다. 괜찮아. 그러나, 문자열 (예 : MessageA* msg = [something].fromString(str))에서 메시지 (구체적인 형식의 메시지)를 구성해야합니다. 주어진 문자열이 MessageA의 생성에 적합하지 않다면 NULL을 얻고 싶습니다. 나는이 작업에 두 가지 방법을 볼 수파생 클래스의 팩토리 메소드

A) MessageFactory 그러나

class MessageFactory 
    { 
     IMessage* fromString(const std::string& str); 
    }; 

    ... 
    MessageFactory mf; 
    MessageA* msg = dynamic_cast< MessageA* >(mf.fromString(str)); 
    if (msg) { ... } 

dynamic_cast으로,이 내가 피하려는 dynamic_cast는을 사용합니다. 각 파생 클래스

static MessageA* fromString(const std::string& str) 
{ 
    return stringIsOk(str) ? new MessageA() : NULL; 
} 

에서

B) 팩토리 메소드는 더 나은 솔루션이 있습니까? 나는 일반적인 디자인에서 뭔가를 바꿔야 할까? 고맙습니다.

UPDATE 언젠가

내가 즉, 내가 문자열에서 받아야 메시지의 종류

void sendRequest() 
{ 
... 
std::string response; 
MessageA* msg = fromString(response); 
// here i should only check if string is valid for MessageA 
} 

알고 있지만 언젠가 내가 나에게 올 것이다 모르겠어요 :

void processMessage(const std::string& str) 
{ 
    IMessage* msg = fromString(str); 
    if (msg) 
    { 
     MessageA* msgA = dynamic_cast< MessageA* >(msg); 
     if (msgA) 
     ... 
    } 
} 
+0

'MessageA *'로 변환하려면 정말로 필요합니까? 'IMessage *'충분하지 않아? – Asha

+2

악용 사례입니다. 'MessageA'와'MessageA'만을 원한다는 것을 이미 알고 있다면, 직접 ('boost :: optional '를 반환하는) 직접 파싱 함수를 작성할 수 있습니다. 다형성 계층은 불필요한 것처럼 보입니다. 통상의 팩토리는'IMessage *'를 돌려줍니다. –

+0

@KerrekSB 다른 종류의 메시지를 받아야합니다. 가끔 언젠가는 그 유형을 기대할 수 있습니다. 메시지 처리 메커니즘은 각 종류의 메시지를 다르게 처리해야합니다. – Kael

답변

0

IMessage에서 파생 된 모든 클래스를(또는 특정 공장)으로 등록 할 수 있습니다. 프로그램 시작시 정적으로 0 클래스. 이는 일부 정적 인스턴스를 사용하여 수행 할 수 있습니다. 따라서 IMessage 인터페이스에는 순수 가상 메서드 canConstructFrom(string&)이 있어야 문자열이 들어 오면 MessageFactory에 전달하고 팩토리는 해당 문자열에서 생성 할 수있는 파생 클래스를 찾고 올바른 인스턴스를 인스턴스화합니다.

+0

감사합니다. 좋은 해결책입니다. 나는 여기에 묘사 된 것과 동일한 상황에있다. http://stackoverflow.com/questions/2758449/is-my-method-for-avoiding-dynamic-cast-faster-than-dynamic-cast-itself – Kael