设计模式之桥接

时间:2024-03-01 21:08:20

桥接模式的介绍

桥接模式就是通过将抽象部分与实现部分分离,把多种可匹配的使用进行组合。其实就是在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();
        }
    }

不关心具体实现,只是单纯的调用。

仔细看上面的代码,在测试验证部分,我们只是需要使用哪一种付款模式就直接传递值进去就可以,不需要关系具体内部的实现逻辑,也满足单一职责原则和开闭原则。

小寄语

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

我是阿辉,感谢您的阅读,如果对你有帮助,麻烦点赞、转发 谢谢。