2012-09-19 82 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());