代理对象我所理解的设计模式(C++实现)——代理模式(Proxy Pattern)
文章結束給大家來個程序員笑話:[M]
????
概述
????作為C++工程師,免不了要管理內存,內存管理也是C++中的難點,而智能指針采用引用計數的方法很方便的幫我們管理了內存的應用,極大方便了我們的任務效率。而智能指針的這類用法其實就是代理模式的一種,他幫我們控制了該對象的內存應用。
????代理模式就是為其他對象提供一種代理來控制對這個對象的拜訪。
????
????
種類和用途
????Proxy模式根據種類不同,效果也不盡雷同:
????1、近程(Remote)代理:為一個位于不同的地址空間的對象提供一個局域代表對象。這個不同的地址空間可所以在本機器中,也可是在另一臺機器中。近程代理又叫做大使(Ambassador)。好處是系統可以將網絡的細節隱藏起來,使得客戶端不必斟酌網絡的存在。客戶完全可以認為被代理的對象是局域的而不是近程的,而代理對象承當了大部份的網絡通訊任務。由于客戶可能沒有意識到會啟動一個耗費時間的近程調用,因此客戶沒有須要的思想準備。
????2、虛擬(Virtual)代理:根據需要創立一個資源消耗較大的對象,使得此對象只在需要時才會被真正創立。應用虛擬代理模式的好處就是代理對象可以在須要的時候才將被代理的對象加載;代理可以對加載的進程加以須要的優化。當一個模塊的加載非常耗費資源的情況下,虛擬代理的好處就非常顯著。
????3、Copy-on-Write代理:虛擬代理的一種。把復制(克隆)拖延到只有在客戶端需要時,才真正采取行動。
????4、保護(Protector Access)代理:控制對一個對象的拜訪,如果需要,可以給不同的用戶提供不同級別的應用權限。保護代理的好處是它可以在運行時間對用戶的有關權限進行檢查,然后在核實后決定將調用傳遞給被代理的對象。
????5、Cache代理:為某一個目標操作的結果提供臨時的存儲空間,以便多個客戶端可以共享這些結果。
????6、防火墻(Firewall)代理:保護目標,不讓惡意用戶親近。
????7、同步化(Synchronization)代理:使幾個用戶能夠同時應用一個對象而沒有沖突。
????8、智能引用(SmartReference)代理:當一個對象被引用時,提供一些額外的操作,比如將對此對象調用的次數記錄下來等。
????在所有種類的代理模式中,虛擬(Virtual)代理、近程(Remote)代理、智能引用代理(SmartReference Proxy)和保護(Protector Access)代理是最為常見的代理模式。
?
????
類圖和實例
????
????
代理模式所涉及的角色有:
抽象主題角色(Subject):聲明白實在主題和代理主題的共同接口,這樣一來在任何應用實在主題的地方都可以應用代理主題。
代理主題(Proxy)角色:代理主題角色內部含有對真是主題的引用,從而可以在任何時候操作實在主題對象;代理主題角色提供一個與實在主題角色雷同的接口,以便可以在任何時候都可以替換實在主體;控制實在主題的應用,擔任在需要的時候創立實在主題對象(和刪除實在主題對象);代理角色通常在將客戶端調用傳遞給實在的主題之前或以后,都要執行某個操作,而不是單純的將調用傳遞給實在主題對象。
實在主題角色(RealSubject)角色:定義了代理角色所代表的實在對象。
????這里給出一個C++中智能指針的例子,自己代碼從新實現了下:
每日一道理天又快黑了,這座忙碌的城市又將入睡,讓這勞累的“身軀”暫別白日的辛勤,讓它入睡,陪伴著城市中的人們進入夢鄉。當空的彎月正深情地注視著這座城市與城市中的人們,看著家家戶戶的燈漸漸熄滅,它在床頭悄悄奏響“明月曲”……
// TestProxy.cpp : Defines the entry point for the console application. //#include "stdafx.h" #include <assert.h>#define KSAFE_DELETE(p) \if (p) \{ \delete p; \p = NULL; \}class KRefCount { public:KRefCount():m_nCount(0){}public:void AddRef(){m_nCount++;}int Release(){return --m_nCount;}void Reset(){m_nCount=0;}private:int m_nCount; };template <typename T> class KSmartPtr { public:KSmartPtr(void): m_pData(NULL){m_pReference = new KRefCount();m_pReference->AddRef();}KSmartPtr(T* pValue): m_pData(pValue){m_pReference = new KRefCount();m_pReference->AddRef();}KSmartPtr(const KSmartPtr<T>& sp): m_pData(sp.m_pData), m_pReference(sp.m_pReference){m_pReference->AddRef();}~KSmartPtr(void){if (m_pReference && m_pReference->Release() == 0){KSAFE_DELETE(m_pData);KSAFE_DELETE(m_pReference);}}inline T& operator*(){return *m_pData;}inline T* operator->(){return m_pData;}KSmartPtr<T>& operator=(const KSmartPtr<T>& sp){if (this != &sp){if (m_pReference && m_pReference->Release() == 0){KSAFE_DELETE(m_pData);KSAFE_DELETE(m_pReference);}m_pData = sp.m_pData;m_pReference = sp.m_pReference;m_pReference->AddRef();}return *this;}KSmartPtr<T>& operator=(T* pValue){if (m_pReference && m_pReference->Release() == 0){KSAFE_DELETE(m_pData);KSAFE_DELETE(m_pReference);}m_pData = pValue;m_pReference = new KRefCount;m_pReference->AddRef();return *this;}T* Get(){T* ptr = NULL; ptr = m_pData;return ptr;}void Attach(T* pObject){if (m_pReference->Release() == 0){KSAFE_DELETE(m_pData);KSAFE_DELETE(m_pReference);}m_pData = pObject;m_pReference = new KRefCount;m_pReference->AddRef();}T* Detach(){T* ptr = NULL;if (m_pData){ ptr = m_pData;m_pData = NULL;m_pReference->Reset();}return ptr;}private:KRefCount* m_pReference;T* m_pData; };
????
與其他模式的區分
????1)適配器模式Adapter
????適配器Adapter為它所適配的對象提供了一個不同的接口。相反,代理提供了與它的實體雷同的接口。然而,用于拜訪保護的代理可能會拒絕執行實領會執行的操作,因此,它的接口實際上可能只是實體接口的一個子集。
????2) 裝飾器模式Decorator
????盡管Decorator的實現部分與代理相似,但Decorator的目的不一樣。Decorator為對象添加一個或多個功能,而代理則控制對對象的拜訪。?
????
總結
????在軟件系統中,加一個中間層是我們常用的解決方法,這方面Proxy模式給了我們很好的實現。
????
????LCL_data原創于CSDN.NET【http://blog.csdn.net/lcl_data/article/details/8989420】
文章結束給大家分享下程序員的一些笑話語錄: 騰訊的動作好快,2010年3月5日19時28分58秒,QQ同時在線人數1億!剛剛看到編輯發布的文章,相差才2分鐘,然后連專題頁面都做出來了,他們早就預料到了吧?(其實,每人贈送10Q幣,輕輕松松上兩億!)
--------------------------------- 原創文章 By
代理和對象
---------------------------------
轉載于:https://www.cnblogs.com/xinyuyuanm/archive/2013/05/29/3106808.html
總結
以上是生活随笔為你收集整理的代理对象我所理解的设计模式(C++实现)——代理模式(Proxy Pattern)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新冠后遗症不容小觑!《柳叶刀》:超1/8
- 下一篇: Linux下mysql整库备份