1

簡単なデコレータの例を見てみましょう:

struct IStuff {
  virtual void Info()=0;
  virtual ~IStuff() { }
};

class Ugly : public IStuff {
public:
  void Info() { cout  << "Ugly"; }
};

class Shiny : public IStuff {
  IStuff* stuff;
public:
  Shiny(IStuff* stuff) {
    this->stuff = stuff;
  }
  ~Shiny() {
    delete stuff;
  }
  void Info() {
    stuff->Info(); // <------------------------------- call super?
    cout << "->Shiny";
  }
};

int main() {
  IStuff* s = new Ugly();
  s = new Shiny(s); // decorate
  s = new Shiny(s); // decorate more
  s->Info(); // Ugly->Shiny->Shiny
  delete s;
  return 0;
}

これもCallスーパーアンチパターンですか?

Call super は、特定のクラスが、派生サブクラスで、ユーザーがメソッドをオーバーライドし、オーバーライドされた関数自体を特定の時点でコールバックする必要があることを規定する設計パターンです。

ここに少し異なる実装があります 設計上の違いはありますか?

4

1 に答える 1

6

これはCall superではありません。オーバーライドされたバージョンではなく、Info別のインスタンスのメソッドを呼び出します。IStuff

スーパーバージョンを呼び出す:

struct IStuff {
  // If you override this, you MUST call the base class version <-- call super
  virtual void Info()
  {
    // a default implementation.

    std::cout << "Super call ";  
  }
  virtual ~IStuff() { }
};

class Shiny : public IStuff {
public:
  void Info() {
    IStuff::Info();  // don't forget to call base implementation.
    std::cout << "->Shiny";
  }
};

Decorator の一部の実装は、装飾された参照を保持、呼び出し、および管理する責任を負う、Decorator 基本クラスへのスーパー呼び出しを行っています。

struct IStuff 
{
  virtual void Info() = 0;
  virtual ~IStuff() { }
};

class Stuff : public IStuff
{
public:
    void Info() { std::cout << "Basic stuff"; }
};

class StuffDecorator : public IStuff
{
    IStuff* decorated_;
public:
    StuffDecorator(IStuff* decoratedStuff) :
        decorated_(decoratedStuff) {}
    ~StuffDecorator() { delete decorated_; }

    void Info()
    {
        decorated_->Info();
    }
};

class Shiny : public StuffDecorator 
{
public:
  Shiny(IStuff* stuff) : StuffDecorator(stuff) { }

  void Info() 
  {
    StuffDecorator::Info();
    std::cout << "->Shiny";
  }
};

スーパー コールを回避するには、 Decorator とTemplate Methodを組み合わせます。

class StuffDecorator : public IStuff
{
    IStuff* decorated_;
public:
    StuffDecorator(IStuff* decoratedStuff) :
        decorated_(decoratedStuff) {}
    ~StuffDecorator() { delete decorated_; }

    void Info()
    {
        decorated_->Info();
        DoInfo();
    }
private:
    // Template method
    virtual void DoInfo() = 0;
};


class Shiny : public StuffDecorator 
{
public:
  Shiny(IStuff* stuff) : StuffDecorator(stuff) { }
private:
  void DoInfo() 
  {
    std::cout << "->Shiny";
  }
};
于 2012-08-26T14:11:26.057 に答える