2012-09-19 150 views
1
class ITransportProvider 
{ 
public: 
    virtual ~ITransportProvider() { } 

protected: 
    virtual void SendData() = 0; 
    // Concrete TransportProvider will call OnReceiveDataEvent 

    // virtual void RegisterHandlers(std::function<void()> onReceiveDataEvent); 
} 

class Device 
{ 
public: 
    Device(shared_ptr<ITransportProvider> transport) 
     : m_Transport(transport) 
    { 
     // transport->RegisterHandlers(boost::bind(&Device::OnReceiveData, this)); 
    } 

    void SendData() 
    { 
     m_Transport->SendData(); 
    } 

    // Which design pattern to use to get concrete TransportProvider's OnReceiveData event? 
    //void OnReceiveData() 
    //{ 
    //} 

private: 
    shared_ptr<ITransportProvider> m_Transport; 
}; 

我一直在我的ITransportProvider中添加一个“RegisterHandlers”,并让Device在它的c'tor中调用它。 我想知道它在DI/IoC大师眼中的正确性,并希望听到所有建议。依赖注入和事件处理

编辑:

为了澄清,我问,如果有一个从设备解耦TransportProvider除了它是通过DI和观察者模式上述方式的一种更好的方式。

+0

为'ITransportProvider :: OnReceiveData()'的评论说,这将由一个具体的TransportProvider调用,但由于它是纯虚拟的,所以它也需要由具体的TransportProvider实现,所以看起来很奇怪它是抽象接口的一部分。 –

+0

@VaughnCato OnReceiveData不应该在界面中 - 我添加它来说明一个我认为会更清晰的回调(但它显然不会,所以我会删除它)。 –

+0

您需要小心,因为Device析构函数需要注销回调。您可能想使用插槽机制,而使用RAII。 –

回答

0

您有一个合理的设计。解耦可以通过各种不同的权衡以不同的方式在许多不同的层面处理。您的设计适用于您知道发送和接收有关的情况,但Device实例和传输实现之间没有特定的编译时间关系。如果有一个编译时间的关系,您可以使用基于策略的设计:

class TransportProviderA 
{ 
public: 
    void SendData(); 
    virtual void OnReceiveData() = 0; 
} 

template <typename TransportPolicy> 
class Device : public TransportPolicy 
{ 
public: 
    Device(const TransportPolicy &transport_policy) 
     : TransportPolicy(transport_policy) 
    { 
    } 

    // SendData provided by TransportPolicy 

    virtual void OnReceiveData(); // overrides TransportPolicy's template method. 
}; 

然后使用它是这样的:

Device<TransportPolicyA> my_device(TransportPolicyA());