簡介
顧名思義,裝飾模式就是給一個對象增加一些新的功能,而且是動態的,要求裝飾對象和被裝飾對象實現同一個接口,裝飾對象持有被裝飾對象的實例。
角色與職責
Component:抽象接口,可以給這些對象動態地增加職責。
ConcreteComponent:Component的具體對象,也可以對這個對象添加一下職責。
Decorator:裝飾抽閒類,繼承自Component,從Decorator的繼承類來擴展component的功能。
ConcreteDecorator:具體的裝飾對象。
實現
#include <iostream>
using namespace std;
class Car {
public:
Car() {}
virtual void show() = 0;
};
class RunCar : public Car{
public:
RunCar() {}
virtual void show(){
cout << "可以跑" << endl;
}
};
class SwimRunCar : public Car{
public:
SwimRunCar(Car* car){
m_car = car;
}
void swim() {
cout << "可以遊" << endl;
}
virtual void show(){
m_car->show();
swim();
}
private:
Car* m_car;
};
class FlyRunCar : public Car {
public:
FlyRunCar(Car* car) {
m_car = car;
}
void fly() {
cout << "可以飛" << endl;
}
virtual void show() {
m_car->show();
fly();
}
private:
Car* m_car;
};
int main(int argc, char* argv[]) {
Car* car = NULL;
car = new RunCar;
car->show();
SwimRunCar* swimRunCar = new SwimRunCar(car);
swimRunCar->show();
FlyRunCar* flyRunCar = new FlyRunCar(swimRunCar);
flyRunCar->show();
cin.get();
return 0;
}
補充
代理模式與裝飾模式的區別:
這兩個圖可能使我們產生困惑。這兩個設計模式看起來很像。對裝飾器模式來說,裝飾者(decorator)和被裝飾者(decoratee)都實現同一個 接口。對代理模式來說,代理類(proxy class)和真實處理的類(real class)都實現同一個接口。此外,不論我們使用哪一個模式,都可以很容易地在真實對象的方法前面或者後面加上自定義的方法。
然而,實際上,在裝飾器模式和代理模式之間還是有很多差別的。裝飾器模式關注於在一個對象上動態的添加方法,然而代理模式關注於控制對對象的訪問。換句話 說,用代理模式,代理類(proxy class)可以對它的客戶隱藏一個對象的具體信息。因此,當使用代理模式的時候,我們常常在一個代理類中創建一個對象的實例。並且,當我們使用裝飾器模 式的時候,我們通常的做法是將原始對象作爲一個參數傳給裝飾者的構造器。
我們可以用另外一句話來總結這些差別:使用代理模式,代理和真實對象之間的的關係通常在編譯時就已經確定了,而裝飾者能夠在運行時遞歸地被構造。