亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

我所理解的設(shè)計(jì)模式(C++實(shí)現(xiàn))——裝飾者模式

系統(tǒng) 4679 0

解決的問題:

我們在裝飾新家的時(shí)候買了幾幅抽象畫,買回來之后發(fā)現(xiàn)有些加上色彩艷麗的邊框更適合我們,而有的加上玻璃罩之后更能符合我們的使用。那我們來怎么解決這個(gè)問題呢?他需要?jiǎng)討B(tài)的給別的對象增加額外的職責(zé),這就是裝飾者模式的目的。

我們可以通過繼承的方式來給原對象增加新功能,但是裝飾者模式采用組合的方式比生成子類更加靈活。


類圖及樣例實(shí)現(xiàn):

在裝飾模式中的各個(gè)角色有:

抽象構(gòu)件( Component )角色:給出一個(gè)抽象接口,以規(guī)范準(zhǔn)備接收附加責(zé)任的對象。

具體構(gòu)件( ConcreteComponent )角色:定義一個(gè)將要接收附加責(zé)任的類。

裝飾( Decorator )角色:持有一個(gè)構(gòu)件( Component )對象的實(shí)例,并定義一個(gè)與抽象構(gòu)件接口一致的接口。

具體裝飾( ConcreteDecorator )角色:負(fù)責(zé)給構(gòu)件對象 " 貼上 " 附加的責(zé)任。

    #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;

	//動(dòng)態(tài)撤銷其他裝飾 ?
	tank2->run();

	Tank * tank3(tank2);
	tank3->run();
	return 0;
}
  


裝飾者與適配者模式的區(qū)別:

1. 關(guān)于新職責(zé):適配器也可以在轉(zhuǎn)換時(shí)增加新的職責(zé),但主要目的不在此。裝飾者模式主要是給被裝飾者增加新職責(zé)的。

2. 關(guān)于原接口:適配器模式是用新接口來調(diào)用原接口,原接口對新系統(tǒng)是不可見或者說不可用的。裝飾者模式原封不動(dòng)的使用原接口,系統(tǒng)對裝飾的對象也通過原接口來完成使用。(增加新接口的裝飾者模式可以認(rèn)為是其變種 -- “半透明”裝飾者)

3. 關(guān)于其包裹的對象:適配器是知道被適配者的詳細(xì)情況的(就是那個(gè)類或那個(gè)接口)。裝飾者只知道其接口是什么,至于其具體類型(是基類還是其他派生類)只有在運(yùn)行期間才知道。


要點(diǎn):

1 .裝飾者和被裝飾對象有相同的超類型。

2 .可以用一個(gè)或多個(gè)裝飾者包裝一個(gè)對象。

3 .裝飾者可以在所委托被裝飾者的行為之前或之后,加上自己的行為,以達(dá)到特定的目的。

4 .對象可以在任何時(shí)候被裝飾,所以可以在運(yùn)行時(shí)動(dòng)態(tài)的,不限量的用你喜歡的裝飾者來裝飾對象。

5 .裝飾模式中使用繼承的關(guān)鍵是想達(dá)到裝飾者和被裝飾對象的類型匹配,而不是獲得其行為。

6 .裝飾者一般對組件的客戶是透明的,除非客戶程序依賴于組件的具體類型。在實(shí)際項(xiàng)目中可以根據(jù)需要為裝飾者添加新的行為,做到 半透明 裝飾者。


適用場景與優(yōu)缺點(diǎn):

在以下情況下應(yīng)當(dāng)使用裝飾模式:

1. 需要擴(kuò)展一個(gè)類的功能,或給一個(gè)類增加附加責(zé)任。

2. 需要?jiǎng)討B(tài)地給一個(gè)對象增加功能,這些功能可以再動(dòng)態(tài)地撤銷。

3. 需要增加由一些基本功能的排列組合而產(chǎn)生的非常大量的功能,從而使繼承關(guān)系變得不現(xiàn)實(shí)。

優(yōu)點(diǎn):

1.Decorator 模式與繼承關(guān)系的目的都是要擴(kuò)展對象的功能,但是 Decorator 可以提供比繼承更多的靈活性。

2. 通過使用不同的具體裝飾類以及這些裝飾類的排列組合,設(shè)計(jì)師可以創(chuàng)造出很多不同行為的組合。

缺點(diǎn):

1. 這種比繼承更加靈活機(jī)動(dòng)的特性,也同時(shí)意味著更加多的復(fù)雜性。

2. 裝飾模式會(huì)導(dǎo)致設(shè)計(jì)中出現(xiàn)許多小類,如果過度使用,會(huì)使程序變得很復(fù)雜。

3. 裝飾模式是針對抽象組件( Component )類型編程。但是,如果你要針對具體組件編程時(shí),就應(yīng)該重新思考你的應(yīng)用架構(gòu),以及裝飾者是否合適。當(dāng)然也可以改變 Component 接口,增加新的公開的行為,實(shí)現(xiàn) 半透明 的裝飾者模式。在實(shí)際項(xiàng)目中要做出最佳選擇。


LCL_data原創(chuàng)于CSDN.NET【 http://blog.csdn.net/lcl_data/article/details/8830455

我所理解的設(shè)計(jì)模式(C++實(shí)現(xiàn))——裝飾者模式(Decorator Pattern)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦?。?!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 四虎最新紧急入口 | 99热人人| 久久在线免费视频 | 精品国产免费第一区二区三区日韩 | 国产h片在线观看 | 一个色综合亚洲色综合 | 国产精品热久久毛片 | 色综合久久中文字幕 | 久久亚洲精品一区成人 | 国产一区二区在线观看免费 | 福利视频专区 | 四虎影视在线观看永久地址 | 免费看真人a一级毛片 | 色婷婷综合激情 | 国产国产精品人在线观看 | 麻豆精品久久精品色综合 | 久久99热精品免费观看欧美 | 欧美理论在线观看 | 综合欧美视频一区二区三区 | 亚欧成人在线 | 欧美日韩中文国产一区二区三区 | 成人夜色香网站在线观看 | 毛片你懂的 | 天天草比 | 欧美精品国产一区二区三区 | 日本不卡毛片一二三四 | 色天天综合久久久久综合片 | 国产在线拍揄自揄视频不卡99 | 日本高清不卡视频 | 在线色综合 | 毛片推荐| 亚洲国产成人麻豆精品 | 一区二区免费看 | 国产大尺度福利视频在线 | 国产成人精品第一区二区 | 欧美香蕉视频在线观看 | 国产女人又爽又大 | 日日干日日摸 | 精品精品久久宅男的天堂 | 成人在线一区二区 | 欧美中文字幕在线看 |