Question

I have two kinds of messages: MessageA and MessageB, both derived from abstract class IMessage containing pure virtual method std::string toString(). So i can convert each message to its string representation with pointer to the base class. That's fine. However, i need somehow to construct message (concrete type of message) from the string, for example: MessageA* msg = [something].fromString( str ). I would like to get NULL if given string isn't suitable for construction of MessageA. I can see two approaches to this task:

a) MessageFactory with dynamic_cast

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

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

However, this uses dynamic_cast which i would like to avoid.

b) factory method in each derived class

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

Is there any better solution? Should i change something in general design? Thank you.

UPDATE

Sometime i know what kind of message i should get from string, i.e.

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

but sometime i don't know what will come to me:

void processMessage( const std::string& str )
{
     IMessage* msg = fromString( str );
     if ( msg )
     {
         MessageA* msgA = dynamic_cast< MessageA* >( msg );
         if ( msgA )
         ...
     } 
}
Était-ce utile?

La solution

You could make all classes derived from IMessage register themselves (or rather a specific factory) with a MessageFactory class statically at program start. This can be achieved by using some static instance. The IMessage interface then needs to have a pure virtual method canConstructFrom(string&) such that when a string comes in, you pass that to the MessageFactory and the factory will find out which of the derived classes can be constructed from that string and instantiate the correct one.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top