Фабричные методы в производных классах

У меня есть два вида сообщений: 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 )
...
}
}

0

Решение

Вы можете сделать все классы производными от IMessage зарегистрировать себя (или, скорее, конкретную фабрику) с MessageFactory класс статически при запуске программы. Это может быть достигнуто с помощью некоторого статического экземпляра. IMessage интерфейс должен иметь чистый виртуальный метод canConstructFrom(string&) так, что когда строка приходит, вы передаете это MessageFactory и фабрика узнает, какой из производных классов может быть создан из этой строки, и создаст экземпляр правильного.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector