日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

趣谈设计模式 | 代理模式(Proxy):利用代理来控制对象的访问

發布時間:2024/4/11 asp.net 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 趣谈设计模式 | 代理模式(Proxy):利用代理来控制对象的访问 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 案例:房屋中介
  • 代理模式
    • 代理模式與裝飾器模式
    • 代理模式的應用
      • 遠程代理
      • 虛擬代理
      • 安全代理
      • 智能引用代理
      • 寫時拷貝代理
  • 總結
  • 完整代碼與文檔


由于代理模式相較于前面的其他設計模式來說更加簡單,容易理解,所以為了保證內容不會太少,我除了介紹代理模式外還會重點介紹遠程代理和虛擬代理,以及簡單提及其他的一些代理模式的應用

案例:房屋中介

假設小明準備去外地實習,于是他需要租一間房來居住。

但是由于身在外地,人生地不熟的他根本沒辦法和正在出租房屋的房東聯系,于是他想到了一個好辦法,找到具有人脈的房產中介來代替他租房

有了房產中介的加入,小明就可以通過中介來幫助他聯系房東,進行租房。

但是此時又面臨了一個問題,此時租房的行為是由中介來代為進行的,因此在房東眼里,這間房屋是中介在租,他根本不知道小明的存在。這就導致了一個問題,如果中介翻臉不認賬獨占房屋,又或者房東有急事要通知小明,那該怎么辦呢?

小明讓中介代替他去租房,實際租房的人并不是中介,而是小明。因此我們在中介租房的時候,應該清楚的告知房東租房的對象,于是邏輯圖變化如下

以行為的角度來說,小明和中介要做的事情都是租房,所以在旁觀人眼里,他們兩個人都是尋求租房的人,因此我們可以將他們兩人都歸類為租房者

以代碼的角度來實現的話,我們可以將租房者定義為一個接口

class Tenant { public:virtual ~Tenant() = default;virtual void rentingHouse() = 0; //租房 };

小明也是租房者,因此他會去實現這個接口

class XiaoMing: public Tenant { public:void rentingHouse() override{std::cout << "小明需要租房!" << std::endl;} };

而中介為了讓房東知道租房的真實對象,他會保留小明的個人信息(小明對象的引用),并且他除了執行小明的租房任務以外,還會附加新的邏輯(收取傭金),代碼如下

class Proxy : public Tenant { public:Proxy(Tenant* client): _client(client){}void rentingHouse() override{_client->rentingHouse(); //代理行為std::cout << "中介代替客戶去租房,并收取傭金" << std::endl; //新增的代理邏輯}private:Tenant* _client; //代理的客戶,需要讓目標知道租房的人是誰 };

下面測試一下邏輯是否正確

int main() {Tenant* xiaoming = new XiaoMing(); //小明Proxy* proxy = new Proxy(xiaoming); //中介代理小明的租房行為proxy->rentingHouse(); //中介代替客戶租房delete proxy, xiaoming;return 0; }


小明雖然不認識房東,但是他通過中介幫助他租房,上面所描述的這一系列行為,其實就是代理模式


代理模式

代理模式為其他對象提供一種代理以控制(隔離,使用接口)對這個對象的訪問

代理模式由以下三部分組成

  • Subject:RealSubject和Proxy的共同接口,利用多態的性質來保證RealSubject能夠隨時使用Proxy
  • RealSubject:實體,業務邏輯的真實執行者,同時也是Proxy代表的對象。
  • Proxy:代理,保存了實體的引用使其可以訪問實體,并且實現了Subject接口,保證其能夠隨時利用代理來替代實體,并添加新的附加功能

類圖如下

從之前所舉的例子中,我們不難看出,代理模式的意圖就是通過代理實體,來為其附加新的功能。來達到業務邏輯與附加功能的解耦

在上面的例子中,中介為小明代理后,分析需求、尋找房源、聯系房東、代替租房,這些行為全都由中介來實現,小明只需要關心租房這件事情,這樣我們就達到了解耦合的目的。

如果以工程實踐的角度來講的話,就好比程序員(實體)只需要負責必須的業務功能實現,而對于如:監控、統計、日志等附加的功能就交由運維、數據分析人員(代理)來實現。

但是如果這樣理解的話,那么代理模式豈不是和裝飾器模式一樣,都在為實體對象增加新功能嗎?

代理模式與裝飾器模式

不了解裝飾器模式的可以看看我的往期博客
趣談設計模式 | 裝飾器模式(Decorator):用裝飾來動態擴展功能

搬出裝飾器模式的類圖,我們發現它的結構其實與代理模式非常相似。

裝飾器模式使用裝飾器來包裝實體,而代理模式使用代理來代理實體,他們都是用一個對象將另一個對象包起來,并且把調用委托給實體。并且在這個基礎上,他們都為實體附加了新的行為。

但是在前面的博客中我也說過,雖然大體的結構相同,但是這并不意味這這兩個設計模式一樣,真正決定設計模式的其實是它具體的設計意圖

代理模式的核心意圖是控制對象的訪問代理通過增加與實體類無關的附加行為來達到訪問控制的目的

裝飾器模式的核心意圖是增強對象的功能,通過附加與實體相關的新行為的方式,來增加實體類原本的功能


代理模式的應用

下面講講遠程代理和虛擬代理,并簡單提一下安全代理、智能引用代理、寫時拷貝代理

遠程代理

遠程代理也就是為一個對象在不同的地址空間提供局部代表,這樣可以隱藏一個對象存在于不同地址空間的事實

例如我們借助代理服務器來訪問外網的時候,就是使用的遠程代理。我們將請求直接發送給代理服務器,而后代理服務器將請求轉發到真實服務器并接收服務器的響應,最后代理服務器再將響應的結果歸還給我們。這樣就仿佛我們直接與真實服務器通信一樣。


虛擬代理

虛擬代理,是根據需要創建開銷很大的對象,通過它來存放實例化需要很長時間的真實對象,來達到性能的最優化。

例如我們在網上購物的時候,通常界面上會顯示很多商品圖片,但是由于圖片過多或者圖片過大導致加載速度慢,導致圖片可能立即無法顯示出來。在這段加載的使用中 ,我們就是使用虛擬代理來替代了真實的圖片,而虛擬代理中則存儲了真實圖片的路徑

上圖中的白框即為虛擬代理,我們會先用它來暫時替代真實圖片,并且虛擬代理還會在內部中繼續加載真實圖片,加載后如下

以代碼來實現的話

class Image { public:virtual ~Image() = default;virtual void display() = 0; //顯示圖片 };class RealImage : public Image { public:RealImage(const std::string& imageName): _imageName(imageName){loadImage(); //加載真實圖片}void display() override{std::cout << "顯示真實圖片" << _imageName << std::endl;}void loadImage(){std::cout << "加載真實圖片" << _imageName << std::endl;} private:std::string _imageName; };class ImageProxy : public Image { public:ImageProxy(const std::string& imageName): _imageName(imageName), _image(nullptr){}~ImageProxy(){if(_image){delete _image;}}void display() override{/*顯示等待語句或者圖片*///加載真實圖片if(_image == nullptr){_image = new RealImage(_imageName);}_image->display(); //顯示真實圖片}private:Image* _image; //真實圖片的引用std::string _imageName; //圖片名 };int main() {Image* proxy = new ImageProxy("test.jpg");proxy->display(); //暫時顯示虛擬代理delete proxy;return 0; }

下面的幾種應用比較簡單,因此就簡單描述一下

安全代理

用來控制對真實對象訪問時的權限,通常在對象有不同的訪問權限時使用

最典型的應用即防火墻,通過設定黑白名單以及訪問權限,來控制對真實對象的訪問。

智能引用代理

當真實對象被引用時,代理進行額外的動作

最典型的就是C++中的智能指針中的share_ptr,對于實體資源來說,智能指針就是它的代理。當智能指針第一次引用資源的時候,就會對其進行管理,而當智能指針的生命周期結束,沒有智能指針再引用這個資源時,就將這個資源給釋放掉。

寫時拷貝代理

延遲對象的復制,直到客戶真正需要它時
寫時拷貝代理其實就是將虛擬代理與引用計數機制相結合,最典型的就是Linux中父子進程的寫時拷貝。當父進程創建子進程時,為了避免不必要的拷貝,只有當子進程需要修改數據時,才會將去拷貝父進程的數據,否則繼續使用父進程的數據。


總結

  • 代理模式為其他對象提供一種代理以控制對這個對象的訪問
  • 代理模式用于控制訪問,裝飾器模式用于增強功能,兩者雖然結構相同,但是意圖不同。
  • 將業務邏輯與附加功能解耦合,實體只需要關注自己部分的功能,而不用關心代理所做的事情,職責更加清晰,拓展性更高
  • 在客戶端和實體之間增加代理對象,導致請求的處理速度可能會變慢

完整代碼與文檔

如果有需要完整代碼或者markdown文檔的同學可以點擊下面的github鏈接
github

總結

以上是生活随笔為你收集整理的趣谈设计模式 | 代理模式(Proxy):利用代理来控制对象的访问的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。