2012-08-26 37 views
1

讓我們有一個簡單的裝飾例如:Decorator模式與調用超反模式

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 super反模式?

調用super是一種設計模式,其中一個特定的類規定,在派生的子類中,用戶需要覆蓋方法並在特定點回調覆蓋的函數本身。

這是little different implementation設計有什麼不同嗎?

+4

不,它不是超級呼叫,因爲你沒有調用超類,而是調用了一個包含的對象。 –

回答

6

這不是超級呼叫。您可以調用另一個IStuff實例的Info方法,而不是重寫版本。

調用超版:

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"; 
    } 
}; 

裝飾的一些實施方案正在爲一個裝飾基類超級呼叫,該負責保存,調用和管理飾參考:

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"; 
    } 
}; 
+0

我明白了。我也更新了我的問題[另一個實現](http://www.vincehuston.org/dp/decorator.html),這被接受[這裏](http://stackoverflow.com/questions/2988066/decorator-pattern- in-c),這看起來完全像你的電話超級版本 - 還是我忽略了一些東西? –

+0

@JanTuroň你是對的。我編輯了我的答案,並提供了一個沒有Call超級的靈魂。 – hansmaad