Я разрабатываю библиотеку, которая будет использоваться для перехвата и обработки входящих сообщений из очереди сообщений. Пользователи библиотеки будут писать свои собственные функции обработки сообщений для различных типов полученных сообщений.
У меня есть класс MessageConsumer
, который должен обрабатывать сообщения разных типов. Я объединил все функции-обработчики в абстрактный базовый класс под названием MessageHandlerBase
. Пользователи библиотеки будут наследовать это и писать свои MessageHandler
классы.
Соответствующие части определения MessageConsumer
:
class MessageConsumer {
protected:
const MessageHandlerBase* m_mesgHandler;
public:
MessageConsumer( const std::string& brokerURI,
const std::string& inputQueueName,
const MessageHandlerBase* messageHandler);
virtual ~MessageConsumer() { this->cleanup(); }
void runConsumer();
virtual void onMessage( const Message& message )
{
// code to receive and parse messages ...
if ( message is of type 1 ) {
m_mesgHandler->handle_message_type_1(message);
else if ( message is of type 2 ) {
m_mesgHandler->handle_message_type_2(message);
// ... and so on for different types of messages
}
};
И определение MessageHandlerBase
равно
class MessageHandlerBase {
public:
virtual void handle_message_type_1( const Message& ) const =0;
virtual void handle_message_type_2( const Message& ) const =0;
virtual void handle_cms_exception() const {}
virtual void handle_transfer_interrupted() const {}
virtual void handle_transfer_resumed() const {}
};
Пользователи обычно просто заботятся об обработке сообщений типа 1 и 2, поэтому я просто сделал их чисто виртуальными.
Моя большая проблема заключается в следующем: При реализации своих собственных MessageHandler
классов handle_message_type_1
и handle_message_type_2
методов пользователям необходим доступ к методам одного (или, возможно, нескольких) из их вспомогательных классов. Как сделать эти классы доступными для MessageHandler
, не делая их глобальными? Я могу передать класс в качестве void*
аргумента handle_message_type_1
, но я не хочу этого, потому что (i) что, если мне нужно передать более одной функции, и (ii) тогда мне нужно изменить вызов в MessageConsumer
; Я хочу полностью абстрагировать эти детали обработки сообщений от MessageConsumer
.
Есть ли более элегантный способ обработки всего этого?