設計模式之橋接

橋接模式的介紹

橋接模式就是通過將抽象部分與實現部分分離,把多種可匹配的使用進行組合。其實就是在A類中含有B類接口,通過構造函數傳遞B類的實現,這個B類就是設計的橋。

它是一種結構型設計模式,可將一個大類或一系列緊密相關的類拆分為抽象和實現兩個獨立的層次結構,從而能在開發時分別使用。

其實簡單說就是將一個複雜類/對象進行拆分,拆分為接口(抽象)和實現,利用接口中的某一實例變量來調用實現的某一塊邏輯實現(這個過程最最重要的就是通過構造函數來聲明和傳遞)。

橋接模式的結構

1、抽象部分:提供高層控制邏輯,依賴於完成底層實際工作的實現對象。

2、實現部分:為所有具體聲明通用接口。抽象部分僅能通過在這裡聲明的方法與實現對象進行交互。

抽象部分可以列出和實現部分一樣的方法,但是抽象部分通常聲明一些複雜行為,這些行為依賴於多種由實現部分聲明的原語操作。

3、具體實現:實現部分的對象模塊,繼承於實現部分。

4、精確抽象:提供控制邏輯的變體,與其父類一樣,它們通過實現接口與不同的實現進行交互。

一般情況下,客戶端只關心如何與抽象部分合作,但是客戶端需要將抽象對象與一個實現對象連接在一起。


  • 想拆分或重組一個具有多重功能的龐雜類
  • 希望在幾個獨立維度上擴展一個類
  • 需要在運行時切換不同實現方法

設計模式並不是一種對類進行組織的方式,它還能用於溝通意圖 和解決問題。

橋接模式的優缺點

優點:

  • 可創建與平台無關的類和程序

  • 客戶端代碼只與高層抽象部分交互,不會接觸到平台的詳細信息(具體的實現方式)

  • 滿足開閉原則。可以新增抽象部分和實現部分,且它們之間不會相互影響

  • 單一職責原則。抽象部分專註於處理高層邏輯,實現部分處理平台細節。

缺點:

  • 別的高內聚的類中使用此模式,不然會越來越複雜。

橋接、狀態模式和策略模式的接口都非常相似。實際上,它們都基於組合模式 :即將工作委派給其他對象,不過也各自解決了不同的問題。

層次結構中的第一層(抽象部分)將包含對第二層(實現部分)對象的引用。抽象部分能將一些對自己的調用委派給實現部分的對象。

所有的實現部分都有一個通用接口,因此它們能在抽象部分內部相互替換。

Demo

    /// <summary>
    /// 支付類  (抽象部分)
    /// </summary>
    public class Pay
    {
        protected IPayMode _padMode;                    

        public Pay(IPayMode padMode)
        {
            this._padMode = padMode;
        }

        public virtual string Validation(int uId,string uName) 
        {
            return "驗證情況彙報:"+_padMode.IsControl(uId);
        }
    }

具體的實現

    /// <summary>
    /// 支付寶支付  (具體實現類)
    /// </summary>
    class zfbPay:Pay
    {
        public zfbPay(IPayMode _padMode)
            : base(_padMode)
        { 

        }

        public override string Validation(int uId, string uName)
        {
            var isValue =_padMode.IsControl(uId);
            return "支付寶正在進行驗證操作 ," + isValue + ",用戶:" + uName;
        }
    }
    /// <summary>
    /// 微信支付  (具體實現類)
    /// </summary>
    class wxPay:Pay
    {
        public wxPay(IPayMode padMode) :base(padMode){

        }        

        public override string Validation(int uId, string uName)
        {
            var isValue = _padMode.IsControl(uId);
            return "微信正在進行驗證操作:" + isValue+",用戶:"+uName;
        }
    }

接口部分

   /// <summary>
    /// 支付模式 
    /// 人臉識別、密碼識別
    /// </summary>
    public interface IPayMode
    {
        /// <summary>
        /// 是否滿足風控要求
        /// </summary>
        /// <param name="uId"></param>
        /// <returns></returns>
        string IsControl(int uId); 
    }
    /// <summary>
    /// 人臉識別
    /// </summary>
    public class FaceRecognition : IPayMode
    {
        public string IsControl(int uId)
        {            
            return "人臉識別成功,你的ID為 " + uId + "滿足風控要求,支付成功。";
        }
    }

    /// <summary>
    /// 賬號密碼
    /// </summary>
    public class PasswardInput:IPayMode
    {
        public string IsControl(int uId)
        {            
            return "密碼識別成功,你的ID為 " + uId + "滿足風控要求,支付成功。";
        }
    }

測試驗證

    class Program
    {
        static void Main(string[] args)
        {
            Pay wxPay = new wxPay(new FaceRecognition());
            var result=wxPay.Validation(001,"阿輝");
            Console.WriteLine(result);

            Pay zfbPay = new zfbPay(new PasswardInput());
            result=zfbPay.Validation(002,"阿七");
            Console.WriteLine(result);
            Console.ReadKey();
        }
    }

不關心具體實現,只是單純的調用。

仔細看上面的代碼,在測試驗證部分,我們只是需要使用哪一種付款模式就直接傳遞值進去就可以,不需要關係具體內部的實現邏輯,也滿足單一職責原則和開閉原則。

小寄語

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

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