2016-12-07 5 views
1

ほとんどの場合、古いコードを扱う場合、あるクラスが単なる呼び出しを別のクラスに転送するという状況があります。何かを制御する古いコントローラがあるとしますが、それらのいくつかは新しいクラスに専念できるとします。さて、古いコントローラは、新しいクラスインタフェースを呼び出します。クラスのインターフェイスの複製

Ex。今

class Controller { 
    public: 
    void addObject(const std::string & id, 
     const Object * obj) { 
     m_Wrk.addObject(id, obj); 
    } 
    private: 
    Worker m_Wrk; 
}; 

class Worker { 
    public: 
    void addObject(const std::string & id, 
     const Object * obj) { 
     //do actual adding 
    } 
}; 

、ソフトウェアのテストについて考えるとき、インターフェイスは、両方のクラスでテストする必要があるかもしれません、コントローラテストの労働者の変更を確認する必要があるとして、それはないほとんどがそうであるように、コントローラでは困難です。

この使用法は特に悪いことですか、上に説明したように既存のコードでこの種のデザインを使用しても問題ありません。

おかげ

+1

「m_Wrk」はポインタでなければなりませんか? – alexeykuzmin0

+0

typoそれは必ずしも必要ではありません。 –

+0

これは本質的にPIMPLではありません。私はその質問を理解するのに苦労していると思う。 ソフトウェアのテストを考えているときは、インタフェースを両方のクラスでテストする必要があります。コントローラでは、作業者の変更を確認する必要がほとんどないため、コントローラではより難しいでしょう。コントローラテスト。 この使用法は特に悪いことですか、上で説明したように既存のコードでこの種のデザインを使用しても問題ありません。 – SmittyBoy

答えて

0

それは、このコードが良いか悪いかどうかを答えるのは難しい - それは状況によって異なります。問題のコード(m_Wrkフィールドがポインタでなければならないという事実を除いて)はPImplパターンであり、種類はbridgeです。このパターンは、抽象化と実装を分割して独立に変更できるようにするために使用します。

たとえば、C++ライブラリを作成し、パブリックインターフェイスに変更がない場合に変更されない安定したABIを提供したい場合は、Controllerインターフェイスをヘッダーに入れ、 Workerクラスの宣言を行い、Workerのインタフェースと実装の両方を.cppファイルに入れます。 Workerが変更された場合、Controller ABIは変更されません。実装の詳細がControllerクラスに直接配置されている場合、ABIが変更される可能性があります。

また、そのようなパターン(一般的にブリッジ)では、与えられた抽象化のさまざまな実装を使用できます。したがって、継承をLiskov置換の観点からインタフェース拡張と継承で分離することは可能です。

また、ControllerWorkerと同じインターフェイスを実装する場合、将来はproxyパターンのようないくつかの追加の動作を実装できます。

これらの状況のいずれかがプロジェクトで発生した場合(または将来発生する可能性がある場合)は、おそらく良いコードでしょう。いいえ、それは単なる不要な合併症です。

関連する問題