C++設計形式之署理形式。本站提示廣大學習愛好者:(C++設計形式之署理形式)文章只能為提供參考,不一定能成為您想要的結果。以下是C++設計形式之署理形式正文
媒介
芳華老是那樣,逝去了才開端回味;年夜先生活也是在不經意間就溜走了,如今下班的時刻,偶然還會思念年夜學時,年夜家在一路玩游戲的時間。年夜學愛好玩游戲,然則可悲的校園網,速度能把人逼瘋了;還好,後來弄了一個游戲署理,總算能勉委曲強的玩了兩年。時至昔日,敲起鍵盤寫設計形式的時刻,又想起了那些美妙的時間。好了,這是一篇技巧文章,而不是抒懷復古的散文;思路再回到這篇文章下去,游戲署理,是個甚麼器械,有了它就可以讓我們玩游戲的延遲立馬上去了。明天,我其實不會去總結游戲署理是若何完成的,重點是經由過程游戲署理這個例子來總結設計形式中的署理形式。
甚麼是署理形式?
在GOF的《設計形式:可復用面向對象軟件的基本》一書中對署理形式是如許說的:為其他對象供給一種署理以掌握對這個對象的拜訪。聯合下面的游戲署理的例子和上面的圖,我們來停止剖析一下。之前你是如許玩游戲:
如今有了游戲署理,你是如許玩游戲:
署理辦事器干了甚麼?它取代你去和游戲辦事器停止交互。它拜訪游戲辦事器的速度比你應用校園網拜訪游戲辦事器的速度快許多。所以,你的游戲延遲就上去了。
署理形式分為四類:長途署理,虛署理,掩護署理和智能援用。鄙人面應用場所會對這四種停止分離引見。
UML類圖
Proxy
1.保留一個援用使得署理可以拜訪實體。若RealSubject和Subject的接口雷同,Proxy會援用Subject,就相當於在署理類中保留一個Subject指針,該指針會指向RealSubject;
2.供給一個與Subject的接口雷同的接口,如許署理便可以用來替換實體;
3.掌握對實體的存取,並能夠擔任創立和刪除它;
4.其它功效依附於署理的類型,例如:
長途署理擔任對要求及其參數停止編碼,並向分歧地址空間中的實體發送已編碼的要求;
虛署理可以緩存實體的附加信息,以便延遲對它的拜訪;
掩護署理檢討挪用者能否具有完成一個要求所必需的拜訪權限。
Subject:界說RealSubject和Proxy的共用接口,如許就在任何應用RealSubject的處所都可使用Proxy;
RealSubject:界說Proxy所署理的實體。
應用場所
下面也總結了,署理形式分為長途署理,虛署理,掩護署理和智能援用這四種,而分為這四種,就是對應分歧的應用場所的。
1.長途署理為一個對象在分歧的地址空間供給部分署理;
2.虛署理依據需求創立開支很年夜的對象;
3.掩護署理掌握原始對象的拜訪;掩護署理用於對象應當有分歧的拜訪權限的時刻;
4.智能援用代替了簡略的指針,它在拜訪對象時履行一些附加操作,它的典范用處包含:
對指向現實對象的援用計數,如許當該對象沒有援用時,可以主動釋放它;
當第一次援用一個耐久對象時,將它裝入內存;
在拜訪一個現實對象前,檢討能否曾經鎖定了它,以確保其他對象不克不及轉變它。
代碼完成
最簡略的完成,對上述UML類圖的直接代碼表現:
#include <iostream>
using namespace std;
#define SAFE_DELETE(p) if (p) { delete p; p = NULL;}
class CSubject
{
public:
CSubject(){};
virtual ~CSubject(){}
virtual void Request() = 0;
};
class CRealSubject : public CSubject
{
public:
CRealSubject(){}
~CRealSubject(){}
void Request()
{
cout<<"CRealSubject Request"<<endl;
}
};
class CProxy : public CSubject
{
public:
CProxy() : m_pRealSubject(NULL){}
~CProxy()
{
SAFE_DELETE(m_pRealSubject);
}
void Request()
{
if (NULL == m_pRealSubject)
{
m_pRealSubject = new CRealSubject();
}
cout<<"CProxy Request"<<endl;
m_pRealSubject->Request();
}
private:
CRealSubject *m_pRealSubject;
};
int main()
{
CSubject *pSubject = new CProxy();
pSubject->Request();
SAFE_DELETE(pSubject);
}
下面的完成,就是對署理形式的最原始表現,如今供給一個有血有肉的現實運用級的表現:
#include <iostream>
#include <windows.h>
using namespace std;
#define SAFE_DELETE(p) if (p) { delete p; p = NULL; }
class KRefCount
{
public:
KRefCount():m_nCount(0){}
public:
unsigned AddRef(){ return InterlockedIncrement(&m_nCount); }
unsigned Release(){ return InterlockedDecrement(&m_nCount); }
void Reset(){ m_nCount = 0; }
private:
unsigned long m_nCount;
};
template <typename T>
class SmartPtr
{
public:
SmartPtr(void)
: m_pData(NULL)
{
m_pReference = new KRefCount();
m_pReference->AddRef();
}
SmartPtr(T* pValue)
: m_pData(pValue)
{
m_pReference = new KRefCount();
m_pReference->AddRef();
}
SmartPtr(const SmartPtr<T>& sp)
: m_pData(sp.m_pData)
, m_pReference(sp.m_pReference)
{
m_pReference->AddRef();
}
~SmartPtr(void)
{
if (m_pReference && m_pReference->Release() == 0)
{
SAFE_DELETE(m_pData);
SAFE_DELETE(m_pReference);
}
}
inline T& operator*()
{
return *m_pData;
}
inline T* operator->()
{
return m_pData;
}
SmartPtr<T>& operator=(const SmartPtr<T>& sp)
{
if (this != &sp)
{
if (m_pReference && m_pReference->Release() == 0)
{
SAFE_DELETE(m_pData);
SAFE_DELETE(m_pReference);
}
m_pData = sp.m_pData;
m_pReference = sp.m_pReference;
m_pReference->AddRef();
}
return *this;
}
SmartPtr<T>& operator=(T* pValue)
{
if (m_pReference && m_pReference->Release() == 0)
{
SAFE_DELETE(m_pData);
SAFE_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)
{
SAFE_DELETE(m_pData);
SAFE_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;
};
class CTest
{
public:
CTest(int b) : a(b) {}
private:
int a;
};
int main()
{
SmartPtr<CTest> pSmartPtr1(new CTest(10));
SmartPtr<CTest> pSmartPtr2(new CTest(20));
pSmartPtr1 = pSmartPtr2;
}
智能指針應用援用計數完成時,就是最好的應用署理形式的例子。在下面的例子中,SmartPtr就是一個署理類,而T* m_pData才是現實的數據。SmartPtr署理現實的數據,去完成了指針的行動,添加了援用計數,從而完成了智能指針。
總結
我在第一次接觸署理形式的時刻,看它的UML類圖,發明它和適配器形式的類適配器很像,再一看,又和裝潢形式異常像;不細心辨別,真的是很輕易凌亂的。上面就做簡略的辨別,說多了也都是“詭辯”了。
1.適配器Adapter為它所適配的對象供給了一個分歧的接口。相反,署理供給了與它的實體雷同的接口。但是,用於拜訪掩護的署理能夠會謝絕履行實領會履行的操作,是以,它的接話柄際上能夠只是實體接口的一個子集。
2.雖然Decorator的完成部門與署理類似,但Decorator的目標紛歧樣。Decorator為對象添加一個或多個功效,而署理則掌握對對象的拜訪。
我在這裡停止辨別,你們看了,也就像我在句斟字嚼一樣;這就是構造型設計形式;它們之間都有一些纖細的差異。你也能夠說,在適配器形式停止接口適配時,添加一些數據轉換就釀成了長途署理;你也能夠說裝潢形式固然功效紛歧樣,在我看來,年夜同小異;是的,不論你怎樣說,就像1000個讀者心中有1000個哈姆雷特一樣,每一個人對設計形式的懂得都是紛歧樣的;最主要的是我們能在現實運用中停止活學活用,假如能做到這個;不論甚麼設計形式,那只是一個名字,就像關於窮人來講,錢只是一個銀行卡上的一個數字一樣。
最初,我深信分享使我們加倍提高,等待年夜家和我分享你的設計形式心得。