設計模式學習之Decorator模式
在OO設計和開發過程中,可能會遇到以下情況:需要為一個已經定義好的類新增新的職責,通常情況下定義一個新的類繼承定義好的類,這樣會帶來一個問題:通過繼承的方式解決這樣的問題帶來了系統的複雜性和繼承深度變得很深;而Decarator提供了一種給類增加職責的方法,不是通過繼承實現,而是通過組合實現;結構圖如下:
在結構圖中,ConcreteComponent和Decorator需要同樣的介面,因此ConcreteComponent和Decorator有相同的父類,這裡會有人問,讓Decorator直接維護一個指向ConcreteComponent引用(指標)不就可以達到相同的效果了,答案是肯定的但也是否定的。肯定的是可以通過這個方式實現,否定的是不要採用這種方式實現,因為通過這種方式你就只能為這個特定的ConcreteComponent提供修飾操作了,當有了一個新的ConcreteComponent時又需要新建一個Decorator類來實現;但是通過類圖ConcreteComponent和Decorator有一個公共的基類,就可以利用OO中多型的思想來實現只要是Component型別的物件都可以提供修飾操作的類這種情況下就算新建100個Component型別的類ConcreteComponent,也都可以由Decorator一個類來搞定,這就是Decorator模式的關鍵所在了。
其實現程式碼如下:
#ifndef _DECORATOR_H
#define _DECORATOR_H
class Component
{
public:
Component();
virtual ~Component();
virtual void Operation();
};
class ConcreteComponent : public Component
{
public:
ConcreteComponent();
virtual ~ConcreteComponent();
void Operation();
};
class Decorator : public Component
{
public:
Decorator(Component* pCom);
virtual ~Decorator();
void Operation();
protected:
Component* pMCom;
};
class ConcreteDecorator : public Decorator
{
public:
ConcreteDecorator(Component* pCom);
virtual ~ConcreteDecorator();
void Operation();
void AddedBehavior();
};
#endif
#include "Decorator.h"
#include <iostream>
Component::Component()
{
}
Component::~Component()
{
}
void Component::Operation()
{
}
ConcreteComponent::ConcreteComponent()
{
}
ConcreteComponent::~ConcreteComponent()
{
}
void ConcreteComponent::Operation()
{
cout<<"ConcreteComponent operation..."<<endl;
}
Decorator::Decorator(Component* pCom)
{
this->pMCom = pCom;
}
Decorator::~Decorator()
{
}
void Decorator::Operation()
{
cout<<"Decorator operation..."<<endl;
}
ConcreteDecorator::ConcreteDecorator(Component* pCom) : Decorator(pCom)
{
}
ConcreteDecorator::~ConcreteDecorator()
{
}
void ConcreteDecorator::AddedBehavior()
{
cout<<"ConcreteDecorator opration..."<<endl;
}
void ConcreteDecorator::Operation()
{
pMCom->Operation();
this->AddedBehavior();
}
#include "Decorator.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
Component* com = new ConcreteComponent();
Decorator* dec = new ConcreteDecorator(com);
dec->Operation();
delete dec;
return 0;
}