設計模式學習之裝飾模式和代理模式

學習設計模式的過程應該是一個迭代的過程,學東西的時候不用追求一遍就掌握、理解透徹(很多情況也是不可能的)。看書看不懂、思想沒有理解,可以反覆去讀、去思考。因爲實戰經驗少,書中給出的例子也有限,所以設計模式的學習可以先大概按書中的例子理解,至於真正應用,可以在後面實踐中嘗試將這些思維融合到考慮過程中。先將這些模式大概瞭解一下,因爲現在實戰有限,所以很多模式只能表層體會,後面有時間再回過頭來再重新學習,可能會有更深層次的體會


1.裝飾模式
定義:動態地給一個對象添加一些額外的職責(不重要的功能,只是偶然一次要執行), 就增加功能來說,裝飾模式比生成子類更爲靈活。建造過程不穩定,按正確的順序串聯起來進行控制。

描述:當你向舊的類中添加新代碼時,一般是爲了添加核心職責或主要行爲。而當需要加入的僅僅是一些特定情況下才會執行的特定的功能時(簡單點就是不是核心應用的功能),就會增加類的複雜度。裝飾模式就是把要添加的附加功能分別放在單獨的類中,並讓這個類包含它要裝飾的對象,當需要執行時,客戶端就可以有選擇地、按順序地使用裝飾功能包裝對象。裝飾模式是用來包裝對象的,每個裝飾對象的實現就和如何使用這個對象分離開了,每個裝飾對象只關心自己的功能,不需要關心如何被添加到對象鏈當中,裝飾模式是爲已有功能動態添加更多功能的一種方式。

實例:

#include <string>
#include <iostream>
using namespace std;
//人
class Person
{
private:
	string m_strName;
public:
	Person(string strName)
	{
		m_strName=strName;
	}
	Person(){}
	virtual void Show()
	{
		cout<<"裝扮的是:"<<m_strName<<endl;
	}
};
//裝飾類
class Finery :public Person
{
protected:
	Person* m_component;
public:
	void Decorate(Person* component)
	{
		m_component=component;
	}
	virtual void Show()
	{
		m_component->Show();
	}
};
//T 恤
class TShirts: public Finery
{
public:
	virtual void Show()
	{
		cout<<"T Shirts"<<endl;
		m_component->Show();
	}
};
//褲子
class BigTrouser :public Finery
{
public:
	virtual void Show()
	{
		cout<<"Big Trouser"<<endl;
		m_component->Show();
	}
};
//客戶端
int main()
{
	Person *p=new Person("小李");
	BigTrouser *bt=new BigTrouser();
	TShirts *ts=new TShirts();
	bt->Decorate(p);
	ts->Decorate(bt);
	ts->Show();
	return 0;
}

 

應用場合:當系統是向舊的類中添加新的代碼來實現新功能時,這些新加的代碼僅僅是爲了滿足一些只在某種特定情況下才會執行的特殊行爲的需要,裝飾模式把每個要裝飾的功能放在單獨的類中,並讓這個類包裝它所要裝飾的對象,因此,當需要執行特殊行爲時,客戶代碼就可以在運行時根據需要有選擇地、按順序地使用裝飾功能包裝對象

優點:把類中的裝飾功能從類中搬移去除,簡化原有的類,有效地把類的核心職責和裝飾功能區分開了,而且可以去除相關類中重複的裝飾邏輯

2.代理模式
定義:爲其他對象提供一種代理以控制對這個對象的訪問

描述:代理模式其實就是在訪問對象時引入一定程度的間接性,通過這種間接性,附加多種用途,代理就是真實對象的代表。

實例:

#include <string>
#include <iostream>
using namespace std;
//定義接口
class Interface
{
public:
	virtual void Request()=0;
};
//真實類
class RealClass : public Interface
{
public:
	virtual void Request()
	{
		cout<<"真實的請求"<<endl;
	}
};
//代理類
class ProxyClass : public Interface
{
private:
	RealClass* m_realClass;
public:
	virtual void Request()
	{
		m_realClass= new RealClass();
		m_realClass->Request();
		delete m_realClass;
	}
};
//客戶端:
int main()
{
	ProxyClass* test=new ProxyClass();
	test->Request();
	return 0;
}

應用場合:
遠程代理:可以隱藏一個對象在不同地址空間的事實
虛擬代理:通過代理來存放需要很長時間實例化的對象
安全代理:用來控制真實對象的訪問權限
智能引用:當調用真實對象時,代理處理另外一些事

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章