[設計模式]結構模式-裝飾器模式(C++描述)

[設計模式]結構模式-裝飾器模式(C++描述)

second60 20180429

1. 什麼是裝飾器

當我們爲一個現有類A添加新的職責時,我們可能會定義新類B繼承現有類,再添加新的操作。但是通過繼承會使問題變得越來越複雜,如果類B又有新操作時,是否又在定義個類C來繼承B呢?這樣加深了繼承的複雜度和深度,代碼也越來越難維護。

 

裝飾器就是爲了解決新加類職責,繼承實現的弊端,而是通過組合來實現。

 

2. 裝飾器結構圖

 

Component: 抽象構件角色功能類和裝飾器的基類。(真實對象和裝飾對象有相同接口)

ConcreteComponent: 構件實現類。

Decorator: 裝飾類,持有一個抽象構件的引用。接受客戶端的請求。

ConcreteDecorator: 裝飾實現類,負責對構件對象新加操作。

 

代碼:

// 抽象構件基類

class Component

{

public:

virtual ~Component(){}

virtual void operation(){}

};

// 構件實現類

ConcreteComponent: public Component

{

public:

virtual void operation(){cout << “ConcreteComponent::operation” << endl;}

};

 

//裝飾器

Decorator: public Component

{

public:

Decorator(Component *component){ _component=component; }

virtual void operation(){cout << “Decorator::operation”<< endl;}

private:

Component *_component;

};

 

// 具體裝飾器

ConcreteDecorator: public Decorator

{

public:

ConcreteDecorator(Component* component):Decorator(component){}

void operation(){cout << “ConcreteDecorator::operation” endl;}

void new_operation(){cout << “ConcreteDecorator::new_operation” endl;}

}

 

3 例子

現有一類汽車,汽車可以跑,但現在需求增加,要求汽車,可以有水裏遊的功能,也有汽車可以飛行的功能。

 

分析:

1. 這裏的水裏遊和飛的汽車,是在原有的汽車上的裝飾,所以可以用裝飾模式來實現。

2. 水裏流和飛的汽車,有一個抽象類汽車類,可以擴展汽車的原有功能。

 

代碼:

// 汽車抽象類

class  CarComponent

{

public:

virtual  ~CarComponent(){}

virtual void move();

};

 

// 普通汽車

class  CommonCar: public CarComponent

{

public:

void move(){cout << “CommonCar::move” << endl;}

};

 

// 汽車裝飾類

class DecoratorCar: public CarComponent

{

public:

DecoratorCar(CarComponent *carComponent){_carComponent = carComponent;}

virtual void move(){_carComponent->move();}

private:

CarComponent *_carComponent;

};

 

// 會游水的車

class SwimCar: public DecoratorCar

{

public:

SwimCar(CarComponent *carComponent): DecoratorCar(carComponent){}

void move()

{

DecoratorCar::move();

swim();

}

void swim(){cout << “swim” << endl;}

}

//會飛的車

class  FlyCar: public  DecoratorCar

{

public:

FlyCar(CarComponent *carComponent): DecoratorCar(carComponent){}

void move()

{

DecoratorCar::move();

fly();

}

void fly(){cout << “fly” << endl;}

}

 

// 使用

int main()

{

// 普通汽車

CommonCar *commonCar = new CommonCar();

commonCar->move();

// 裝飾讓汽車能遊

SwimCar *swimCar = new SwimCar(car);

swimCar->move();

//裝飾讓汽車會飛

FlyCar *flyCar = new FlyCar(car);

flyCar->move();

return 0;

}

 

分析:

現有的普通汽車,只需加裝飾,即可添加不同的功能,同時,如果需要添加更多的操作,只需新加裝飾子類即可。

 

4 優點

a) 擴展對象功能,用組合的方式實現,減少類的個數

b) 可以對一個對象多次裝飾,創造出不同行爲的組合,得到功能更強大的對象

c) 具體構建類和具體裝飾類,可以獨立變化,可根據需求增加子類

 

5 缺點

a) 裝飾模式複雜理解難,排查問題麻煩

 

 

6 裝飾模式和橋接模式

相同點:

a) 橋接模式是多個可變維度,通過組合,減少類的方法(類維度擴展)

b) 裝飾模式是爲現有類添加職責,通過組合,減少類的方法(類操作擴展)

 

7 總結

裝飾模式,降低了系統的耦合度,可以動態的增加或刪除對象的職責,並使得需要裝飾的具體構建類和具體裝飾類可以獨立變化,以便增加新的具體構建類和具體裝飾類。

 

發佈了70 篇原創文章 · 獲贊 40 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章