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 の専門家の目から見たその正しさを知りたいですし、すべての提案を聞きたいです。

編集:

明確にするために、DIとオブザーバーパターンを介した上記の方法以外に、トランスポートプロバイダーをデバイスから切り離すより良い方法があるかどうかを尋ねています。

4

1 に答える 1

0

あなたは合理的なデザインを持っています。デカップリングは、さまざまなトレードオフを使用して、さまざまな方法でさまざまなレベルで処理できます。送信と受信が関連していることがわかっている場合に適した設計ですが、デバイスインスタンスとトランスポート実装の間に特定のコンパイル時の関係はありません。コンパイル時の関係があった場合は、ポリシーベースの設計を使用できます。

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());
于 2012-09-19T06:04:13.347 に答える