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 )
...
}
}
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.