本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7699301.html,记录一下学习过程以备后续查用。

    一、引言

    今天我们要讲结构型设计模式的第二个模式--桥接模式,也有叫桥模式的。桥在我们现实生活中经常是连接着A地和B地,再往后来发展,桥引申为一种纽带,比如,丝绸之路是连接亚洲和欧洲的桥梁。有了桥,我们出行更方便了,不需要绕路或搭船。针对桥的使用环境来说,桥解决了跨越和衔接的问题。在设计模式中的桥接模式也有类似的概念,是连接了两个不同维度的东西,而且这两个维度又有强烈的变化。

    二、桥接模式介绍

    桥接模式:英文名称--Bridge Pattern;分类--结构型。

    2.1、动机(Motivate)

    一般游戏场景中,装备都会有自己固有的逻辑。比如枪支,有型号,同时又支持在不同的介质平台上使用,这样就使得游戏的装备具有了两个变化的维度。一个变化的维度为“平台的变化”,另一个变化的维度为“型号的变化”。如果我们要写代码实现这款游戏,难道我们针对每种平台都实现一套独立的装备吗?复用在哪里?如何应对这种“多维度的变化”?如何利用面向对象技术来使得装备可以轻松地沿着“平台”和“型号”两个方向变化,而不引入额外的复杂度?

    2.2、意图(Intent)

    将抽象部分与实现部分分离,使它们都可以独立地变化。--《设计模式》Gof

    桥接模式不能只是认为是抽象和实现的分离,它其实并不仅限于此。其实两个都是抽象的部分,更确切的理解,应该是将一个事物中多个维度的变化分离。

    2.3、结构图(Structure)

C#设计模式学习笔记:(7)桥接模式

    2.4、模式的组成

    桥接模式的结构包括Abstraction、RefinedAbstraction、Implementor、ConcreteImplementorA和ConcreteImplementorB五个部分,其中:

    1)抽象化角色(Abstraction):抽象化给出定义,并保存一个对实现化对象(Implementor)的引用。

    2)修正抽象化角色(Refined Abstraction):扩展抽象化角色,改变和修正父类对抽象化的定义。

    3)实现化角色(Implementor):这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定与抽象化角色的接口定义相同。实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。

    4)具体实现化角色(Concrete Implementor):这个角色给出实现化角色接口的具体实现。

    在桥接模式中,两个类Abstraction和Implementor分别定义了抽象与行为类型的接口,通过调用两接口的子类实现抽象与行为的动态组合。

    2.5、桥接模式的具体实现

    今天我们就以数据库为例来写该模式的实现。每种数据库都有自己的版本,但是每种数据库在不同的平台上实现又是不一样的。比如,微软的SqlServer数据库有2000、2005、2008、2012、2014、2016、2017版本,后面还会有更新的版本,并且这些版本都是运行在Windows操作系统下的。如果要提供Lunix操作系统下的SqlServer怎么办呢?如果又要提供IOS操作系统下的SqlServer数据库该怎么办呢?这个情况就可以使用桥接模式,也就是Brige模式。

    下面看看具体的实现:

C#设计模式学习笔记:(7)桥接模式
    class Program
    {
        /// <summary>
        /// 该抽象类就是抽象接口的定义,该类型就相当于是Abstraction类型。
        /// </summary>
        public abstract class Database
        {
            //通过组合方式引用平台接口,此处就是桥梁,该类型相当于Implementor类型。
            protected PlatformImplementor platformImplementor;

            //通过构造器注入,初始化平台实现。
            protected Database(PlatformImplementor implementor)
            {
                platformImplementor = implementor;
            }

            //创建数据库,该操作相当于Abstraction类型的Operation方法。
            public abstract void Create();
        }

        /// <summary>
        /// 该抽象类就是实现接口的定义,该类型就相当于是Implementor类型。
        /// </summary>
        public abstract class PlatformImplementor
        {
            //该方法就相当于Implementor类型的OperationImp方法
            public abstract void Process();
        }

        /// <summary>
        /// SqlServer2000版本的数据库,相当于RefinedAbstraction类型。
        /// </summary>
        public class SqlServer2000 : Database
        {
            //构造函数初始化
            public SqlServer2000(PlatformImplementor implementor) : base(implementor) { }

            public override void Create()
            {
                platformImplementor.Process();
            }
        }

        /// <summary>
        /// SqlServer2005版本的数据库,相当于RefinedAbstraction类型。
        /// </summary>
        public class SqlServer2005 : Database
        {
            //构造函数初始化
            public SqlServer2005(PlatformImplementor implementor) : base(implementor) { }

            public override void Create()
            {
                platformImplementor.Process();
            }
        }

        /// <summary>
        /// SqlServer2000版本的数据库针对Unix操作系统的具体实现,相当于ConcreteImplementorA类型。
        /// </summary>
        public class SqlServer2000UnixImplementor : PlatformImplementor
        {
            public override void Process()
            {
                Console.WriteLine("SqlServer2000针对Unix操作系统的具体实现。");
            }
        }

        /// <summary>
        /// SqlServer2005版本的数据库针对Unix操作系统的具体实现,相当于ConcreteImplementorB类型。
        /// </summary>
        public sealed class SqlServer2005UnixImplementor : PlatformImplementor
        {
            public override void Process()
            {
                Console.WriteLine("SqlServer2005针对Unix操作系统的具体实现。");
            }
        }

        static void Main(string[] args)
        {
            #region 桥接模式
            //针对不同平台进行扩展,也就是子类化,这个是独立变化的。
            PlatformImplementor SqlServer2000UnixImp = new SqlServer2000UnixImplementor();

            //数据库版本也可以进行扩展和升级,也进行独立的变化。
            Database SqlServer2000Unix = new SqlServer2000(SqlServer2000UnixImp);

            //以上就是两个维度的变化。

            //现在就可以针对Unix操作系统进行操作了。
            SqlServer2000Unix.Create();

            Console.Read();
            #endregion
        }
    }
View Code

相关文章:

  • 2021-08-21
  • 2021-07-06
  • 2021-08-18
  • 2021-07-06
  • 2021-07-25
  • 2021-08-20
猜你喜欢
  • 2022-01-21
  • 2021-08-04
  • 2021-09-11
  • 2021-06-22
  • 2022-12-23
  • 2021-06-16
  • 2021-10-04
相关资源
相似解决方案