1. 程式人生 > >Decorator裝飾設計模式(結構型)

Decorator裝飾設計模式(結構型)

第八個設計模式

意圖
動態地給一個物件新增一些額外的職責。有時候我們需要給某個物件而不是整個類新增一些功能。

適用性

  • 在不影響其他物件的情況下,以動態、透明的方式給單個物件新增職責。
  • 處理那些可以撤消的職責。
  • 當不能採用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴充套件,
  • 為支援每一種組合將產生大量的子類,使得子類數目呈爆炸性增長。另一種情況可能是因為類定義被隱藏,或類定義不能用於生成子類。

結構
這裡寫圖片描述

參與者
Component:定義一個物件介面,可以給這些物件動態地新增職責。

ConcreteComponent: 定義一個物件,可以給這個類的物件新增一些職責

Decorator:維持一個指向Component物件的指標,並定義一個與Component介面一致的介面

ConcreteDecorator:向元件新增職責。

實現

#include <string>  
#include <iostream>  
#include <memory>  
using namespace std;  

//抽象類Tank  
class Tank  
{  
public:  
    virtual void shot()=0;  
    virtual void run()=0;  

public:  
    virtual ~Tank()  
    {  
        cout<<"in the destructor of Tank"
<<endl; } }; //具體類 T50 class T50:public Tank { public: void shot() { cout<<"Tank T50 shot()"<<endl; } void run() { cout<<"Tank T50 run()"<<endl; } public: virtual ~T50() { cout<<"In the destructor of T50"
<<endl; } }; //具體類T75 class T75:public Tank { public: void shot() { cout<<"Tank T75 shot()"<<endl; } void run() { cout<<"Tank T75 run()"<<endl; } public: virtual ~T75() { cout<<"In the destructor of T75"<<endl; } }; //抽象類,Decorator class Decorator:public Tank { protected: Tank* tank; public: Decorator(Tank* tank):tank(tank) {} //具體的坦克的裝飾類 virtual ~Decorator() { cout<<"In the destructor of Decorator"<<endl; } public: void shot() { tank->shot(); } void run() { tank->run(); } }; class InfraredDecorator: public Decorator { private: string infrared;//這就是所謂的addAtrribute public: InfraredDecorator(Tank* tank):Decorator(tank) {} virtual ~InfraredDecorator() { cout<<"in the destructor of InfraredDecorator"<<endl; } public: void set_Infrared(const string &infrared) { this->infrared=infrared; } string get_infrared() const { return infrared; } void run() { tank->run(); set_Infrared("+Infrared"); cout<<get_infrared()<<endl; } void shot() { tank->shot(); } }; class AmphibianDecorator:public Decorator { private: string amphibian; public: AmphibianDecorator(Tank* tank):Decorator(tank) {} ~AmphibianDecorator() { cout<<"in the destructor of AmphibianDecorator"<<endl; } public: void set_amphibian(const string &hibian) { this->amphibian=hibian; } string get_amphibian() const { return amphibian; } public: void run() { tank->run(); set_amphibian("+amphibian"); cout<<get_amphibian()<<endl; } void shot() { tank->shot(); } }; int main(int argc, char **argv) { //給T50增加紅外功能 Tank* tank1(new T50); Tank* pid1(new InfraredDecorator(tank1)); pid1->shot(); cout<<endl; pid1->run(); cout<<endl; cout<<endl<<"---------------"<<endl; //給t75增加紅外、兩棲功能 Tank* tank2(new T75); tank2->run(); Tank* pid2(new InfraredDecorator(tank2)); Tank* pad2(new AmphibianDecorator(pid2)); pad2->shot(); cout<<endl; pad2->run(); cout<<endl; cout<<endl<<"--------------"<<endl; //動態撤銷其他裝飾 ? tank2->run(); Tank * tank3(tank2); tank3->run(); return 0; }

適用場景與優缺點:

在以下情況下應當使用裝飾模式:
1.需要擴充套件一個類的功能,或給一個類增加附加責任。
2.需要動態地給一個物件增加功能,這些功能可以再動態地撤銷。
3.需要增加由一些基本功能的排列組合而產生的非常大量的功能,從而使繼承關係變得不現實。

優點:
1. Decorator模式與繼承關係的目的都是要擴充套件物件的功能,但是Decorator可以提供比繼承更多的靈活性。
2. 通過使用不同的具體裝飾類以及這些裝飾類的排列組合,設計師可以創造出很多不同行為的組合。

缺點:
1. 這種比繼承更加靈活機動的特性,也同時意味著更加多的複雜性。
2. 裝飾模式會導致設計中出現許多小類,如果過度使用,會使程式變得很複雜。
3. 裝飾模式是針對抽象元件(Component)型別程式設計。但是,如果你要針對具體元件程式設計時,就應該重新思考你的應用架構,以及裝飾者是否合適。當然也可以改變Component介面,增加新的公開的行為,實現“半透明”的裝飾者模式。在實際專案中要做出最佳選擇。

相關推薦

Decorator裝飾設計模式結構

第八個設計模式 意圖 動態地給一個物件新增一些額外的職責。有時候我們需要給某個物件而不是整個類新增一些功能。 適用性 在不影響其他物件的情況下,以動態、透明的方式給單個物件新增職責。 處理那些可以撤消的職責。 當不能採用生成子類的方法進行擴充時。一種情

javascript設計模式裝飾模式結構模式

javascript設計模式之裝飾器模式 js的設計模式分為建立型模式,結構型模式和行為模式 結構模式描述瞭如何組合物件以提供新的功能。 裝飾器模式是一種常見的結構型模式,我們可以以一個基礎物件為基礎,來給它加上若干個裝飾物件以拓展其功能。 下面是示

Java——設計模式結構模式

一、介面卡模式(不相容結構的協調) 在介面卡模式中引入了一個被稱為介面卡(Adapter)的包裝類,而它所包裝的物件稱為適配者(Adaptee),即被適配的類。介面卡的實現就是把客戶類的請求轉化為對適配者的相應介面的呼叫。也就是說:當客戶類呼叫介面卡的方法時,在介面卡類的內部將呼叫適配者類的方法,而這個過程

【知識積累】一、設計模式建立

定義公共介面和實現類: 一、工廠方法模式(Factory Method) 1、普通工廠模式 2、多工廠方法模式 3、靜態工廠方法模式 二、抽象工廠模式(Abstract Factory) 三、建造者模式(Builder)

設計模式建立:Java常用23種設計模式之單例模式詳解以及Java程式碼實現

可以說單例模式是所有設計模式中最簡單的一種。 單例模式就是說系統中對於某類的只能有一個物件,不可能出來第二個。 單例模式也是23中設計模式中在面試時少數幾個會要求寫程式碼的模式之一。主要考察的是多執行緒下面單例模式的執行緒安全性問題。 1.多執行緒安全單例模式例項一(不使用同步鎖)

spring 與設計模式建立之Builder模式

一、前言 將一個複雜的物件構建與它的表示分離,使得同樣的構建過程可以建立不同的表示,實現構建物件的過程與部件解耦。生活中許多這樣的例子,例如大學4年的學習,每一年的學習成績會最終影響4後的績點。電腦汽

java設計模式行為之迭代器模式

package com.mcc.core.designPattern.behavior.iterator.doubleIterator; /**  * 迭代器實現  *  * @author <a href="mailto:[email protected]">menergy</a

橋接模式結構

一:背景 這裡拿大話設計模式一書中的例子來說,有兩種實體,手機和手機軟體;我們在每種手機品牌上都有各種的軟體app來執行,如何表示呢?一般有兩種維度劃分,通過手機品牌分類,每種品牌下分軟體類;另一中以手機軟體app型別劃分,型別下分手機品牌;可以發現,這兩種拓

設計模式裝飾模式Decorator結構

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

設計模式十一裝飾模式Decorator-結構

裝飾者模式Decorator 在程式開發中,有時候開發人員會使用繼承來擴充套件物件的功能,使用者的需求是多變的,也就造成了使用繼承會造成程式碼的大範圍改動,其實擴充套件物件的功能,採用組合比繼承要好的多,當用戶需要變動時,只要將物件組合發生變化就可以了,不會大

"圍觀"設計模式(13)--結構裝飾模式Decorator Pattern

修飾模式,是面向物件程式設計領域中,一種動態地往一個類中新增新的行為的設計模式。就功能而言,修飾模式相比生成子類更為靈活,這樣可以給某個物件而不是整個類新增一些功能。----WIKIPEDIA 個人

Java學習--設計模式結構模式

and 它的 null spa bubuko imp AD mco flyweight 一、裝飾器模式(Decorator Pattern)   1、概念    裝飾器模式(Decorator Pattern)允許向一個現有的對象添加新的功能,同時又不改變其結構。這種類

設計模式十一代理模式Proxy結構

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

設計模式介面卡模式Adapter結構

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

設計模式橋連模式Bridge結構

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

代理模式 PROXY Surrogate 結構 設計模式十四

代理模式 PROXY 別名Surrogate 意圖 為其他的物件提供一種代理以控制對這個物件的訪問。 代理模式含義比較清晰,就是中間人,中介公司,經紀人... 在計算機程式中,代理就表示一個客戶端不想或者不能夠直接引用一個物件 而代理物件可以在客戶端和目標物件之間起到中介

結構設計模式對比 設計模式十六

結構型設計模式 結構型模式關注於整體最終的結構,通過繼承和組合,構建出更加複雜的結構 進而提供更加強大的邏輯功能 七種結構型模式 介面卡模式(Adapter Pattern) 組合模式(Composite P

Java設計模式十二結構模式:享元模式

一、定義: 享元模式,也就是說在一個系統中如果有多個相同的物件,那麼只共享一份就可以了,不必每個都去例項化一個物件。比如說一個文本系統,每個字母定一個物件,那麼大小寫字母一共就是52個,那麼就要定義52個物件。如果有一個1M的文字,那麼字母是何其的多,如果每個字母都定義一個

結構設計模式7種裝飾模式

結構類設計模式(7種)之裝飾器模式 一、快餐點餐系統 又提到了那個快餐點餐系統,不過今天我們只以其中的一個類作為主角:飲料類。首先,回憶下飲料類: class Beverage(): name = "" price = 0.0 type = "BEVERAGE"

23種設計模式之享元模式結構,7 Flyweight,c++實現

程式碼實現:#include<iostream>#include<list>#include<string>#include<map>usingnamespace std;classPerson{public:Person(st