【问题标题】:Confusion about callback function design回调函数设计的困惑
【发布时间】:2011-05-18 03:02:43
【问题描述】:

我正在设计一个库,用于拦截和处理来自消息队列的传入消息。图书馆用户将为收到的不同类型的消息编写自己的消息处理函数。

我有一个需要处理不同类型消息的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_1handle_message_type_2 方法时,用户需要从一个(或可能更多)他们的帮助类中访问方法。这些类如何提供给MessageHandler,而不使它们成为全球性的?我可以将类作为void* 参数传递给handle_message_type_1,但我不想这样做,因为(i)如果我需要传递多个函数并且(ii)那么我需要更改@987654334 中的调用@;我想从MessageConsumer 中完全抽象出这些消息处理细节。

有没有更优雅的方式来处理整个事情?

【问题讨论】:

    标签: c++ message-queue listener


    【解决方案1】:

    如何使MessageHandler 可以使用这些类,而不使它们全局化?

    用户需要从您的类派生。是什么阻止他们将各种数据成员放入派生中,引用他们需要的任何内容?

    这是使用仿函数而不是函数指针的主要优点:它使void* userData 过时了。

    【讨论】:

    • 谢谢,是的,他们将从MessageHandlerBase 派生来实现自己的处理程序。但是,帮助程序类已经实现,因此不希望更改该代码。例如,有一个名为Tracker 的类,在处理type_1 的消息时需要调用track() 方法。他们是否应该使用多重继承,在这种情况下来自MessageHandlerBaseTracker
    • 当他们创建派生的MessageHandler 对象时,用户将传入他们需要使用的辅助类的任何指针,并将它们存储在子类的私有数据中。
    • @recipriversexclusion 任何实现 MessageHandlerBase 的类都可以: a) 从任何其他需要的类派生; b) 包含任何其他需要的对象; c) 通过指针或引用引用其他对象。一般来说,这三个选项都是可行的。使用对您的程序设计最有意义的任何一种(或组合)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    • 2011-11-21
    • 2020-09-07
    • 2018-04-26
    相关资源
    最近更新 更多