1

例:

class Display
{
public:
    virtual void display() = 0;
};

class PageDisplay : public Display
{
public:
    void display() { /* ... */ }
};

class DisplayDecorator : public Display
{
public:
    DisplayDecorator(Display* display) : m_display(display) {}
    virtual void display() { m_display->display(); }
private:
    Display* m_display;
};

class BorderDecorator : public DisplayDecorator
{
public:
    BorderDecorator(Display* display) : DisplayDecorator(display) {}
    virtual void display() { DisplayDecorator::display(); /* do border stuff here ... */ }
};

int main()
{
    Display* pageDisp = new BorderDecorator(new PageDisplay());
    pageDisp->display();
}

したがって、これはデコレータパターンのかなり基本的な実装です。しかし、たとえば、BorderDecorator具象クラス内にデコレータFROMを追加したいとします。したがって、BorderDecorator::display関数は次のようになります。

virtual void display()
{ 
    /*
    I need to add a decorator that will display a slider bar at the side of the screen, 
    and that will wrap the PageDisplay decorator so that it will run before the page display.
    Is there a clean way to get my base class' m_display pointer so that I can do something like this:
    */
    m_display = new SliderDecorator(m_display);

    DisplayDecorator::display();
    /* do border stuff here ... */
}

また、この例の場合、クライアント関数(この場合はメイン)内からSliderDecoratorを適用したいだけであることも知っています。頭のてっぺんから、(私が取り組んでいるもの以外に)コンクリートデコレータオブジェクト内からデコレータを追加する必要がある理由の良い例を思い付くことができませんが、我慢してください。私にはそうする正当な理由があります。また、抽象デコレータオブジェクト(この例ではm_display)の抽象基本クラスポインタをプライベートではなく保護し、例のように具体的なデコレータオブジェクト内からデコレータを追加できることも知っていますが、これは次のようになります。データのカプセル化が崩れるため、悪い考えです。デコレータは、デコレートするオブジェクトと不適切に相互作用する可能性があります。そうは言っても、それが私の唯一の選択肢ですか?コンクリートデコレータの「デコレーション」機能内から、複合デコレータを別のデコレータでラップして、通常のように続行するためのより良い方法はありますか?

4

2 に答える 2

1

つまりね。クライアントは、どのデコレータを適用するかを知っている必要があります。クライアントがBorderDecoratorを呼び出すとき、スライダーのある境界線ではなく境界線のみを期待しているため、このロジックを内部のデコレーターにプッシュしても意味がありません。クライアントコードで、動的に指定できる必要がある複数のデコレータをチェーンする場合は、ChainofResponsibilityパターンを使用できます。

于 2012-06-29T06:33:08.260 に答える
0

もちろん?基本的に、追加するデコレータの特殊化、または一般的に使用されるデコレータの組み合わせを構築するためのユーティリティクラス/メソッドを実行します。

コードの適切な統合のように聞こえます。どうぞ、大丈夫ですよ。

于 2012-06-29T06:45:54.427 に答える