У меня есть два типа сообщений: MessageA
и MessageB
, оба производные от абстрактного класса IMessage
, содержащего чистый виртуальный метод std::string toString()
. Поэтому я могу преобразовать каждое сообщение в его строковое представление с указателем на базовый класс. Это нормально. Однако мне нужно как-то построить сообщение (конкретный тип сообщения) из строки, например: MessageA* msg = [something].fromString( str )
. Я хотел бы получить NULL, если данная строка не подходит для построения MessageA
. Я вижу два подхода к этой задаче:
а) MessageFactory
с dynamic_cast
class MessageFactory
{
IMessage* fromString( const std::string& str );
};
...
MessageFactory mf;
MessageA* msg = dynamic_cast< MessageA* >( mf.fromString( str ) );
if ( msg ) { ... }
Однако при этом используется dynamic_cast, которого я хотел бы избежать.
б) фабричный метод в каждом производном классе
static MessageA* fromString( const std::string& str )
{
return stringIsOk( str ) ? new MessageA() : NULL;
}
Есть ли лучшее решение? Должен ли я что-то изменить в общем дизайне? Спасибо.
ОБНОВЛЕНИЕ
Иногда я знаю, какое сообщение я должен получить из строки, т.е.
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 )
...
}
}
MessageA*
?IMessage*
недостаточно? - person Asha   schedule 01.07.2013MessageA
и толькоMessageA
, вы можете написать прямую функцию синтаксического анализа (в идеале возвращающуюboost::optional<MessageA>
). Полиморфная иерархия кажется ненужной. Типичная фабрика вернетIMessage *
. - person Kerrek SB   schedule 01.07.2013