­

設計模式之代理

代理模式介紹

代理

代理模式 是一種結構型設計模式,讓你能夠提供對象的替代品或其佔位符。代理控制着對於原對象的訪問,並允許在將請求提交給對象前後進行一些處理。

其實說通俗點,就好比我們平時生活中的購買機票,火車票,我們以前的做法是去縣上或市區的每一個代理點去購買,你不需要關心代理點的工作人員去哪、購買車票,你只需要給錢說購買的地方,其餘的一切都交由他負責。那麼在這個購票的過程中,代理點的購票員就相當於是一種代理模式。

代理模式最常見的地方就是數據庫操作部分,對於數據庫的操作很多時候我們都在使用代理的模式來進行,比如我們常用的ORM其實說白了也是代理的一種特殊表現形式。

數據庫代理

代理模式結構

  • 服務接口 聲明服務接口,代理必須遵循該接口才能偽裝成服務對象。

  • 服務 類提供一些實用的業務邏輯。

  • 代理 類包含一個指向服務對象的引用成員變量。代理完成其任務(例如延遲初始化、記錄日誌、訪問控制和緩存等)後會將請求傳遞給服務對象。通常情況下,代理會對其服務對象的整個生命周期進行管理。

  • 客戶端 能通過同一接口或代理進行交互,所以你可在一切需要服務對象的代碼中使用代理。

代理模式應用場景

  • 延遲初始化
  • 訪問控制
  • 本地執行遠程服務(遠程代理)
  • 記錄日誌請求
  • 智能引用

代理模式的實現方式

  • 如果沒有現成的服務接口,你就需要創建一個接口來實現代理和服務對象的可交換性。

  • 創建代理類,其中必須包含一個存儲指向服務的引用的成員變量(創建服務並對其整個生命周期進行管理,客戶端通過構造函數將服務傳遞給代理)。

  • 根據需求實現代理方法。在大部分情況下,代理在完成一些任務後應將工作委派給服務對象。

  • 可以考慮新建一個構建方法來判斷客戶端可獲取的是代理還是實際服務。(可在代理類中創建一個靜態方法,也可以創建工廠方法)

  • 可以考慮為服務對象提供延遲初始化操作

Demo

原始類提取的接口

    public interface ISubject 
    {
        void Request();
    }

原始類和代理類的實現

    /// <summary>
    /// 代理的對象  
    /// 在代理類中提前聲明並通過構造函數實例化
    /// </summary>
    public class RealSubject : ISubject
    {
        public void Request()
        {
            Console.WriteLine("打印原始的RealSubject");
        }
    }

    /// <summary>
    /// 代理類 ,實現了ISbuject接口
    /// </summary>
    public class Proxy : ISubject
    {
        private RealSubject _realSubject;
        public Proxy(RealSubject realSubject)
        {
            this._realSubject = realSubject;
        }

        public void Request()
        {
            if (CheakAccess())
            {
                _realSubject.Request();
                LogAcess();
            }
        }

        private bool CheakAccess() 
        {
            Console.WriteLine("Proxy:類  檢測驗證");
            return true;
        }

        private void LogAcess()
        {
            Console.WriteLine("Proxy類,主動輸出LogAcess");        
        }
    }

客戶端和驗證Main方法

    /// <summary>
    /// 驗證的客戶端
    /// 可接收實現了ISubject接口的類
    /// </summary>
    public class Client
    {
        public void ClientCode(ISubject subject)
        {
            subject.Request();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Client client = new Client();

            Console.WriteLine("開始");
            RealSubject realSubject = new RealSubject();
            client.ClientCode(realSubject);

            Console.WriteLine("-------------");
            Proxy proxy = new Proxy(realSubject);
            client.ClientCode(proxy);
            Console.ReadKey();
        }
    }

打印的結果

通過上面的數據庫訪問示意圖和練習的Demo代碼,可以非常清楚的了解代理模式。在我們平時的業務開發過程中,可以多多留意是否有這樣的需求可以滿足代理模式的要求,那麼就大概率可以使用代理模式來實現或重構。

一個好的設計模式,是恰當好處的出現在了業務剛好需要它的時候才是最美妙的。

小寄語

人生短暫,我不想去追求自己看不見的,我只想抓住我能看的見的。

我是阿輝,感謝您的閱讀,如果對你有幫助,麻煩點贊、轉發 謝謝。