2011-07-14 10 views
2

私はプラグインをターゲットにしているフレームワークを設計した結果、私は自分のコードの一部をシングルトンとして実装しました。このクラスは、フレームワーク内から通信している外部プログラムへの接続を処理します。参照を返す関数、失敗した場合に返す関数

外部通信を有効にするのは実行時設定ですが、無効になっている場合は、フレームワーク内のモデルからのアクセスを許可したくありません。 ServiceEnabledfalseであることを考えると、私はgetInstanceが有効Communicatorを返すことができるようにしたくない、今

class Communicator { 
public: 
    static Communicator& getInstance() { 
     static Communicator instance; 
     return instance; 
    } 
    // ... 
private: 
    static bool ServiceEnabled; 
    // Constructors, operator=, etc ... 
} 

:私は頻繁にここで推奨されているバージョンを使用して、それを実装しました。しかし、私は参照を返すので、私は単に0などを返すことはできません...適切な行動は何でしょうか? ServiceEnabledが偽であっても実行を続けることは完全に有効であることに注意してください。

+4

はより良いここにあなたのニーズポインタのスーツを返さないでしょうか? (私は例外をスローすることは、あなたが何をしているのではないと仮定しています) – Mat

+1

'ServiceEnabled'のメンバーはどのオブジェクトがfalseですか? – aschepler

+0

@aschepler:おっと。一定。 – carlpett

答えて

4

static bool IsServiceEnabled(); 

公共の機能を追加し、ServiceEnabledながら、それを呼び出してgetInstance、中に例外をスロー== falseを;

0

私は設計の意思決定をもう一度考えて、おそらく例外クラスを作り、それを投げ捨てます。もちろん、これは相手側で可能な例外を処理する必要があります。

1

適切な行動はあなたが失敗が発生したときに例外をスローすることです:

#include <stdexcept> 

class Communicator { 
public: 
    static Communicator& getInstance() { 
     static Communicator instance; 
     if (ServiceEnabled) 
      return instance; 
     else 
      throw std::exception("Get communicator while service is not enabled"); 
    } 
    // ... 
private: 
    static bool ServiceEnabled; 
    // Constructors, operator=, etc ... 
} 
0

おそらく、あなたが実装するには「有効」

として偽ServiceEnabledとのコミュニケータを検討すべきである、あなたは方法bool IsEnabled()を必要とし、あなたの他の方法があればすぐに戻り、servoceはほとんどの場合、有効とされているかを確認する必要がありますそうではない。

0

副作用のあるすべての呼び出しが無効になっている場合は、クラスを無視するだけです。この方法で、必要なすべての機能を呼び出すことができ、オンかオフかを心配する必要はありません。ユーザーが通信する必要があるかどうかを知るための "IsServiceEnabled"(Henrikの回答)を提供します。

4

実際には多くの可能性があります...リストの始まりは特にありません。

ポインタ

class Communicator { 
public: 
    static Communicator const* Instance(); // returns 0 if not Enabled 
}; 

これは、実際に「より安全」ポインタ型(と主張/ポインタがNULLで、誰かがそれを使用しようとするとスロー)で置き換えることができます。

クエリ+スロー

class Communicator { 
public: 
    static bool IsEnabled(); 
    static Communicator const& Instance(); // throw if not Enabled 
}; 

ヌルオブジェクト

class Communicator { 
public: 
    static Communicator const& Instance(); //returns a null instance if not Enabled 

    void doit() { if (!enabled) { return; } } 
}; 

事実を離れて非表示にすることで、それはあなたのことが有効になっていなかったことをので、私は個人的に、非常に最後のものが好きではありませんユーザが早期に問題に気付かないようにします。すべてを送信したときにトランザクションを登録したことを確認したトランザクションシステムを考えてください/dev/null ...

0

実行時に通信をオン/オフできるようにしたい場合は、有効になっている間Communicator参照を保存し、後で無効にしたときに使用することができます。 この問題は、もちろんシングルトンに固有の問題ではありません。
あなたがそれを処理するために間接の別の層を導入する可能性:

class CommunicatorImpl 
{ 
public: 
    virtual bool isEnabled() const = 0; 
    virtual void doSomething() = 0; 
}; 

class CommunicatorImpl_Enabled : public CommunicatorImpl 
{ 
    public: 
     virtual bool isEnabled() const { return true; } 
     virtual void doSomething() { /* Do something... */} 
}; 


class CommunicatorImpl_Disabled : public CommunicatorImpl 
{ 
    public: 
     virtual bool isEnabled() const { return false; } 
     virtual void doSomething() { throw CommunicationIsDisabled("SRY"); } 
}; 



class Communicator { 
public: 
    static Communicator& getInstance() { 
     static Communicator instance; 
     return instance; 
    } 

    void enable() { m_impl = &m_enabled; } 
    void disable() { m_impl = &m_disabled; } 
    bool isEnabled() const { return m_impl->isEnabled(); } 
    void doSomething() { m_impl->doSomething(); } 

private: 
    CommunicatorImpl* m_impl; 
    CommunicatorImpl_Enabled m_enabled; 
    CommunicatorImpl_Disabled m_disabled; 
} 
関連する問題