深入理解設計模式(23):代理模式

来源:https://www.cnblogs.com/xuwendong/archive/2019/04/08/10318700.html
-Advertisement-
Play Games

一、引言 我們都知道,資料庫連接是很珍貴的資源,頻繁的開關資料庫連接是非常浪費伺服器的CPU資源以及記憶體的,所以我們一般都是使用資料庫連接池來解決這一問題,即創造一堆等待被使用的連接,等到用的時候就從池裡取一個,不用了再放回去,資料庫連接在整個應用啟動期間,幾乎是不關閉的,除非是超過了最大閑置時間。 ...


一、引言

  我們都知道,資料庫連接是很珍貴的資源,頻繁的開關資料庫連接是非常浪費伺服器的CPU資源以及記憶體的,所以我們一般都是使用資料庫連接池來解決這一問題,即創造一堆等待被使用的連接,等到用的時候就從池裡取一個,不用了再放回去,資料庫連接在整個應用啟動期間,幾乎是不關閉的,除非是超過了最大閑置時間。

  但是在程式員編寫程式的時候,會經常使用connection.close()這樣的方法,去關閉資料庫連接,而且這樣做是對的,所以你並不能告訴程式員們說,你們使用連接都不要關了,去調用一個其他的類似歸還給連接池的方法吧。這是不符合程式員的編程思維的,也很勉強,而且具有風險性,因為程式員會忘的。

  解決這一問題的辦法就是使用代理模式,因為代理模式可以替代原有類的行為,所以我們要做的就是替換掉connection的close行為。

二、什麼是代理模式

代理模式——就是給某一個對象提供一個代理,並由代理對象控制對原對象的引用。在一些情況下,一個客戶不想或者不能直接引用一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用。例如電腦桌面的快捷方式就是一個代理對象,快捷方式是它所引用的程式的一個代理。

三、代理模式的結構

 

  (1) Subject(抽象主題角色):它聲明瞭真實主題和代理主題的共同介面,這樣一來在任何使用真實主題的地方都可以使用代理主題,客戶端通常需要針對抽象主題角色進行編程。

       (2) Proxy(代理主題角色):它包含了對真實主題的引用,從而可以在任何時候操作真實主題對象;在代理主題角色中提供一個與真實主題角色相同的介面,以便在任何時候都可以替代真實主題;代理主題角色還可以控制對真實主題的使用,負責在需要的時候創建和刪除真實主題對象,並對真實主題對象的使用加以約束。通常,在代理主題角色中,客戶端在調用所引用的真實主題操作之前或之後還需要執行其他操作,而不僅僅是單純調用真實主題對象中的操作。

       (3) RealSubject(真實主題角色):它定義了代理角色所代表的真實對象,在真實主題角色中實現了真實的業務操作,客戶端可以通過代理主題角色間接調用真實主題角色中定義的操作。

四、代理模式和裝飾模式的異同

代理模式和裝飾模式的代碼實現方式很相同,主要不同點是代理模式關註與被代理對象行為的控制,然而裝飾模式關註於在一個對象上動態的添加方法。

代理模式可以對客戶端隱藏被代理對象的具體實現,代理模式的時候常常是在一個代理類中創建一個對象的實例,當使用裝飾模式的時候,將原始對象轉為一個參數傳遞給裝飾者的構造器中

代理模式強調的是限制,裝飾模式強調的是增強

五、代理模式和委托

      代理:是把一些事情交給某人幫忙去完成。

      委托:是當某件事情發生的時候,順便乾某件事情。委托就相當於一個觸發器罷了。

六、代理模式的種類

在實際開發過程中,代理類的實現比上述代碼要複雜很多,代理模式根據其目的和實現方式不同可分為很多種類,其中常用的幾種代理模式簡要說明如下:

       (1) 遠程代理(Remote Proxy):為一個位於不同的地址空間的對象提供一個本地的代理對象,這個不同的地址空間可以是在同一臺主機中,也可是在另一臺主機中,遠程代理又稱為大使(Ambassador)。

       (2) 虛擬代理(Virtual Proxy):如果需要創建一個資源消耗較大的對象,先創建一個消耗相對較小的對象來表示,真實對象只在需要時才會被真正創建。

       (3) 保護代理(Protect Proxy):控制對一個對象的訪問,可以給不同的用戶提供不同級別的使用許可權。

       (4) 緩衝代理(Cache Proxy):為某一個目標操作的結果提供臨時的存儲空間,以便多個客戶端可以共用這些結果。

       (5) 智能引用代理(Smart Reference Proxy):當一個對象被引用時,提供一些額外的操作,例如將對象被調用的次數記錄下來等。

七、代理模式的應用場景

 代理模式的類型較多,不同類型的代理模式有不同的優缺點,它們應用於不同的場合:

       (1) 當客戶端對象需要訪問遠程主機中的對象時可以使用遠程代理。

       (2) 當需要用一個消耗資源較少的對象來代表一個消耗資源較多的對象,從而降低系統開銷、縮短運行時間時可以使用虛擬代理,例如一個對象需要很長時間才能完成載入時。

       (3) 當需要為某一個被頻繁訪問的操作結果提供一個臨時存儲空間,以供多個客戶端共用訪問這些結果時可以使用緩衝代理。通過使用緩衝代理,系統無須在客戶端每一次訪問時都重新執行操作,只需直接從臨時緩衝區獲取操作結果即可。

       (4) 當需要控制對一個對象的訪問,為不同用戶提供不同級別的訪問許可權時可以使用保護代理。

       (5) 當需要為一個對象的訪問(引用)提供一些額外的操作時可以使用智能引用代理。

八、代理模式的優缺點

優點:

   (1) 能夠協調調用者和被調用者,在一定程度上降低了系統的耦合度。

       (2) 客戶端可以針對抽象主題角色進行編程,增加和更換代理類無須修改源代碼,符合開閉原則,系統具有較好的靈活性和可擴展性。

缺點:

   (1) 由於在客戶端和真實主題之間增加了代理對象,因此有些類型的代理模式可能會造成請求的處理速度變慢,例如保護代理。

       (2) 實現代理模式需要額外的工作,而且有些代理模式的實現過程較為複雜,例如遠程代理。

九、代理模式的實現


class
SchoolGirl //定義 女孩類 { private string name; public string Name { get { return name; } set { name = value; } } }
//抽象主題類聲明瞭真實主題類和代理類的公共方法,它可以是介面、抽象類或具體類,客戶端針對抽象主題類編程,一致性地對待真實主題和代理主題,
interface
IGiveGift //創建一個送禮物的介面 { void GiveDolls(); void GiveFlowers(); void GiveChocolate(); }

//真實主題類繼承了抽象主題類,提供了業務方法的具體實現,
class Pursuit:IGiveGift     //追求者類,使用送禮物的介面
    {
        SchoolGirl mm;          //要追求女孩的名字
        public Pursuit(SchoolGirl mm)
        {
            this.mm = mm;
        }
        public void GiveDolls()
        {
            Console.WriteLine(mm.Name+"送你洋娃娃");
        }
        public void GiveFlowers()
        {
            Console.WriteLine(mm.Name + "送你花");
        }
        public void GiveChocolate()
        {
            Console.WriteLine(mm.Name + "送你巧克力");
        }
    }
//代理類也是抽象主題類的子類,它維持一個對真實主題對象的引用,調用在真實主題中實現的業務方法,在調用時可以在原有業務方法的基礎上附加一些新的方法來對功能進行擴充或約束,
class
Proxy : IGiveGift //定義代理模式,也用送禮物的介面 { Pursuit gg; public Proxy(SchoolGirl mm) //區別在於,代替追求者 送禮物 { gg=new Pursuit(mm); } public void GiveDolls() { gg.GiveDolls(); } public void GiveFlowers() { gg.GiveFlowers(); } public void GiveChocolate() { gg.GiveChocolate(); } }
class Program
    {
        static void Main(string[] args)
        {
            SchoolGirl mm = new SchoolGirl();
            mm.Name = "hanmeimei";

            Proxy daili = new Proxy(mm);

            daili.GiveDolls();
            daili.GiveFlowers();
            daili.GiveChocolate();
        }
    }

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 網站項目經常會遇到一些視頻或者圖片素材的展示功能,那麼就需要自己寫一個功能,就是在一些列表頁面你想要是這個數據的詳細內容,彈框在頁面某個位置 例如這是視頻懸浮展示效果,可自定義自動播放等屬性標簽 又例如這是圖片懸浮展示,可控制懸浮展示與不展示 像上面這樣或者一些其他列表做的一些懸浮彈框展示等,都可以 ...
  • JavaScript_01簡介,基本語法,運算符,和java語言進行對比總結 ...
  • 1,element 表格嵌入CheckBox 效果圖如下: 2,element結合checkBox實現單選效果如下: html代碼: js代碼: ...
  • "use strict": 1、它是 ES5 引入的一條指令,指令不是語句,但非常接近於語句 2、不包含任何語言的關鍵字,指令僅僅是一個包含一個特殊字元串直接量的表達式。對於那些沒有實現 ES5 的 JavaScript 解釋器來說,它只是一條沒有副作用的表達式語句 3、只能出現在腳本代碼的開始或函 ...
  • HTML部分 js部分 ...
  • 接手項目之後,在安裝依賴後,再npm start的過程中報錯./node_modules/history/esm/history.js Module not found: Can't resolve '@babel/runtime/helpers/esm/extends' ...
  • 最近一個星期準備學習一下angular前端框架,因為之前在學習abp框架的時候,都要求前端要掌握angular,所以不得不回來惡補一下了,學習的過程有時間的話會記錄在這裡,方便以後複習。 閑言少敘,下麵來介紹開發環境搭建的步驟: 開發環境搭建 1.安裝node和npm(其實只需要安裝node,因為n ...
  • 前言: 相信大家都打開過層級很多很多的文件夾。如果把第一個文件夾看作是樹的根節點的話,下麵的子文件夾就可以看作一個子節點。不過最終我們尋找的還是文件夾中的文件,文件可以看做是葉子節點。下麵我們介紹一種模式,與這種樹級結構息息相關。當然,今天的主角是HashMap。接下來我們一起來看HashMap中到 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...