2012-02-22 11 views
0

デコレータパターンが、この例のような古いメソッドで継承できないクラスのいくつかのメソッドを拡張するための良い、簡単な標準であることは間違いありません(私はインターフェイスを使用していません)できるだけ短くする)。C++でデコレータパターンを使うべきでしょうか?

using System; 

class Human { ... } 

class Father { 
    public string Info() { 
     return "John"; 
    } 
} 

class Son : Human { // decorating Father 
    Father f = new Father(); 
    public string Info() { 
     return "I am son of "+f.Info(); 
    } 
} 


class Program { 
    public static void Main() { 
     Son s = new Son(); 
     Console.WriteLine(s.Info()); // I am son of John 
     Console.ReadKey(); 
    } 
} 

しかし、我々はC++で多重継承を持っているので、私たちは父情報を(非表示)の代わりに、それを飾ることができます。

#include <string> 
#include <iostream> 
using namespace std; 

class Human { ... }; 

class Father { 
public: 
    string Info() { 
     return "John"; 
    } 
}; 

class Son : public Human, Father { // inherit both 
public: 
    string Info() { 
     return "I am son of " + Father::Info(); 
    } 
}; 

int main() { 
    Son* s = new Son(); 
    cout << s->Info(); // I am son of John 
    cin.get(); 
    return 0; 
} 

私は多くのパターンの理由は、AD-を移動させることであることを理解再使用可能なクラスからアドホッククラスへの論理をホールドするので、再利用可能なクラスはアドホックコードで混乱する必要はありません。しかし、これは多重継承でも​​実現できます。

デコレーションが複数の継承より優れているところを説明することができますか?

+0

に役立ちます。静的継承階層で定義するのではなく、動的にプロセッサを作成する必要があります。 –

+0

複数の継承がある場合は、それを使用できます。 –

答えて

4

デコレータパターンでは、オブジェクトを実行時にデコレートすることができますが、複数の継承はコンパイル時の解決策です。これにより、異なるデコレータを最小限のオーバーヘッドで自由に組み合わせることができますが、複数の継承ではデコレータの組み合わせごとに新しいクラスが必要になります。

また、インターフェイスクラス(純粋な仮想メソッドのみを持つクラス)以外のものを継承していれば、複数の継承を取得するのは難しいです。

+0

@JanTuroň:それは単なるコンパイル時ではありません。複数の継承を使用する場合は、使用したいデコレータの組み合わせごとに新しいクラスを作成する必要があります。その結果、コードに多くのオーバーヘッドが発生します。デコレータは、インターフェイスが適合する限り、飾るものには無関心であるため、最小限のオーバーヘッドで自由に組み合わせることができます。 –

+0

ああ、私はそれを得た。ニースと短い説明、ありがとう! –

0

私の意見では、これはデコレータパターンではなく、あなたは間違った方法で継承を使用しているようです。継承する前に、「Son is a Father」または「SpecificObject」が一般化されたオブジェクトであり、これはあなたが表現するものではありません。

デコレータパターンは、デコレートされるオブジェクトをデコレートするオブジェクトに渡すことによって機能します。典型的な例はGuiのBorderClassで、境界線を使って渡すウィジェットを飾っています。

public class Border : Widget 
    { 
     public Border(Widget decorateMe) 
     { 
      this._toDecorate = decorateMe; 
     } 
     public virtual void draw(gc or whatnot){ 
      gc.drawRectangle(blah); 
      this._toDecorate.draw(gc); 
     } 
    } 

希望これは、私は一般的な例は、デジタル信号処理であると思い

+0

私は知っている - 私のクラスの名前 - 父と息子 - 少し誤解を招く。たぶん私は別の名前と方法を使っていたはずです...今は遅すぎます。 –

+0

と私はクラスが内部から自分自身を飾ることができないことを明らかにしたかったので、装飾されるものはそれに渡されます。 – mindandmedia

関連する問題