創(chuàng)建網(wǎng)站要多少錢seo競(jìng)價(jià)排名
文章目錄
- 定義
- UML圖
- 代理模式主要有以下幾種常見類型:
- 代理模式涉及的主要角色有:
- C++ 代碼示例
定義
代理模式(Proxy Pattern)屬于結(jié)構(gòu)型設(shè)計(jì)模式,它為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問。
通過引入代理對(duì)象,代理模式可以在目標(biāo)對(duì)象的基礎(chǔ)上,增加額外的功能,比如訪問控制、懶加載、緩存等,同時(shí)對(duì)外界隱藏目標(biāo)對(duì)象的實(shí)現(xiàn)細(xì)節(jié),讓調(diào)用者感覺好像是在直接與目標(biāo)對(duì)象進(jìn)行交互。
UML圖
代理模式主要有以下幾種常見類型:
遠(yuǎn)程代理(Remote Proxy):用于代表一個(gè)在不同地址空間(比如網(wǎng)絡(luò)上的不同服務(wù)器)的對(duì)象,使得客戶端可以像訪問本地對(duì)象一樣訪問遠(yuǎn)程對(duì)象。
虛擬代理(Virtual Proxy):根據(jù)需要?jiǎng)?chuàng)建開銷較大的對(duì)象,比如在真正需要訪問對(duì)象時(shí)才去實(shí)例化它,常用于實(shí)現(xiàn)圖片懶加載等功能,在圖片要顯示時(shí)才加載圖片資源。
保護(hù)代理(Protection Proxy):控制對(duì)原始對(duì)象的訪問權(quán)限,根據(jù)不同的權(quán)限決定是否允許調(diào)用者執(zhí)行相應(yīng)的操作。
代理模式涉及的主要角色有:
抽象主題(Subject):定義了真實(shí)主題和代理主題的共同接口,這樣客戶端在使用時(shí)可以以統(tǒng)一的方式與真實(shí)對(duì)象或代理對(duì)象進(jìn)行交互。
真實(shí)主題(Real Subject):實(shí)現(xiàn)了抽象主題接口,是實(shí)際完成業(yè)務(wù)邏輯的對(duì)象,也就是被代理的對(duì)象。
代理(Proxy):同樣實(shí)現(xiàn)了抽象主題接口,內(nèi)部包含一個(gè)指向真實(shí)主題對(duì)象的指針,它可以在調(diào)用真實(shí)主題的方法前后添加額外的邏輯,來實(shí)現(xiàn)對(duì)真實(shí)主題的訪問控制等功能。
C++ 代碼示例
以下是一個(gè)簡(jiǎn)單的代理模式示例,模擬一個(gè)簡(jiǎn)單的圖像加載展示場(chǎng)景,這里使用虛擬代理的思路,先創(chuàng)建代理對(duì)象,在真正需要展示圖像(調(diào)用 display 方法)時(shí)才去加載并展示真實(shí)的圖像(這里只是簡(jiǎn)單模擬加載邏輯)。
#include <iostream>
#include <string>// 抽象主題,定義圖像操作的接口
class Image
{
public:virtual void display() = 0;virtual ~Image() {}
};// 真實(shí)主題,代表實(shí)際的圖像,這里簡(jiǎn)單模擬圖像有個(gè)文件名屬性及加載展示邏輯
class RealImage : public Image
{
private:std::string fileName;
public:RealImage(const std::string& name) : fileName(name) {loadFromDisk();}void display() override{std::cout << "Displaying image: " << fileName << std::endl;}
private:void loadFromDisk(){std::cout << "Loading image from disk: " << fileName << std::endl;}
};// 代理類,代表圖像的代理,在需要時(shí)才創(chuàng)建真實(shí)圖像對(duì)象并調(diào)用其方法
class ProxyImage : public Image
{
private:RealImage* realImage;std::string fileName;
public:ProxyImage(const std::string& name) : realImage(nullptr), fileName(name) {}void display() override{//在此,可以對(duì)被代理的對(duì)象的操作進(jìn)行額外操作;//不允許顯示特定的圖片,異常處理,或者重新解碼顯示,加水印等等任何實(shí)際需求都可以在此添加if (!realImage){realImage = new RealImage(fileName);}realImage->display();}~ProxyImage() {delete realImage;}
};int main()
{// 創(chuàng)建代理對(duì)象,此時(shí)并沒有真正加載圖像Image* image = new ProxyImage("example.jpg");// 第一次調(diào)用 display,會(huì)觸發(fā)真實(shí)圖像的加載和展示image->display();// 第二次調(diào)用 display,因?yàn)橐呀?jīng)加載過了,直接展示,不會(huì)重復(fù)加載image->display();delete image;char t;std::cin>>t;return 0;
}
在上述代碼中:
Image 作為抽象主題,定義了 display 這個(gè)抽象方法,表示圖像展示的操作,客戶端只需要和這個(gè)接口進(jìn)行交互。
RealImage 是真實(shí)主題,它實(shí)現(xiàn)了 Image 接口,內(nèi)部有圖像文件名屬性,并且在構(gòu)造函數(shù)中會(huì)進(jìn)行從磁盤加載圖像的模擬操作,在 display 方法中展示圖像。
ProxyImage 為代理類,它也實(shí)現(xiàn)了 Image 接口,內(nèi)部有一個(gè)指向 RealImage 的指針以及圖像文件名屬性。在 display 方法中,先判斷真實(shí)圖像是否已經(jīng)創(chuàng)建,如果沒有創(chuàng)建就實(shí)例化 RealImage,然后調(diào)用真實(shí)圖像的 display 方法來展示圖像。這樣就實(shí)現(xiàn)了在真正需要展示圖像時(shí)才去加載它的虛擬代理功能,并且在 main 函數(shù)里可以看到,多次調(diào)用展示方法時(shí),后續(xù)調(diào)用不會(huì)重復(fù)加載圖像,提高了效率(在更復(fù)雜的場(chǎng)景下能體現(xiàn)出資源利用等方面的優(yōu)勢(shì))。最后要記得釋放內(nèi)存,避免內(nèi)存泄漏。
仔細(xì)想一下,智能指針好像有點(diǎn)代理模式的意思。