`

【转】设计模式之Bridge(桥接)

 
阅读更多

注释:以下资料都是个人从网上收集起来的,会注明来源地址

 

如果你想要写一个游戏,并且想让这个游戏同时支持PC和手机,那么怎么样的设计可以避免写两套代码,并且不影响可扩展性呢?说起来还是比较简单的,只要把对平台的依赖部分抽取成抽象的接口(比如说绘图部分),并且针对抽取出来的接口,分别实现PC版和手机版就行了。系统的其他部分只要调用那套抽取出来的接口就可以完成所有的功能。这样来看,系统的其他部分是不依赖具体的平台的,也就具有了良好的扩展性。这个就是Bridge模式的应用。

       1、定义 
       将抽象和实现相分离,使二者可以独立的变化。(GOF)

       2、结构图 
 
                                           图一:Bridge模式的一个结构图

 

        3、例子 
        任何设计模式都是应用于不同的需求的,这里我们构造了一个有关汽车的需求来应用Bridge模式。(不过,由于个人对车了解不多,所以有可能例子不是很恰当,不要纠结于这一点哦)

         ★需求 
          1. 概括的讲,我们的需求就是实现各种各样的汽车。从细节上讲,我们知道,汽车
以用途分类,有卡车,巴士,小汽车等类别;
以动力系统分类,有汽油型,柴油型,电力型,天然气型,生物能,油电混合型,太阳能型等等。也就是说,有汽油型的卡车,巴士,小汽车,也有柴油型的卡车,巴士,小汽车,当然还有其他各种类型的卡车,巴士,小汽车。这里为了方便,我们对需求做一个简化,只考虑卡车、巴士,汽油型和柴油型。也就是说,两两组合之后,就会有四种车型:汽油型卡车,柴油型卡车,汽油型巴士和柴油型巴士。

         2. 任何车都有开始和停止的功能。

         3. 卡车有载货的功能,巴士有载客的功能。

         ★初次设计 
根据以上的需求描述,想必所有人都可以设计出如图二所示的类结构来。
 
                   图二:关于汽车的最初的设计图

         ★重构 
        虽然图二所示的图任何人都可以设计出来,但估计没有人是满意这样的设计的。这样的设计,不但重复代码多,而且要扩展或有所修改的话,所有的类都得大动干戈。
这里我们就对其做一次重构。
从需求3我们知道,卡车和巴士分别有专有的功能(载货,载客),并且这个功能是和动力系统无关的,而开车和停止的功能都是与动力系统有关的。所以我们这里先把卡车和巴士区分出来,并且分别实现载货和载客的功能。那么就是如图三所示的结构了。
 
                         图三:一次重构后的设计图

       ★再重构 
       经过图三的重构之后,结构就清晰了些,并且代码的重复度也减少了一部分(载货,载客)。但是我们还是可以看出不足之处,较明显的地方就是,同样的动力系统,它的开始和停止肯定是基本相似的。

其实这里是有一个隐藏需求的。
       1. 对于同一种类型的车来说,无论采用的动力系统是哪一种,其驾驶方法是相同的。也就是说,会开汽油型卡车的司机开起柴油型的卡车来也是驾轻就熟的。否则,有多少种车就得有多少种驾驶方法的话,司机没事就得考驾照了,人手n本驾照,很恐怖的。
       2. 同样,对于同一种动力系统来说,无论安装在哪一种车型上,恐怕主要是动力的大小是不同的,启动和停止的方法(在软件系统中来说应该是接口)应该是相同的。

       下面我们根据以上的隐藏需求对这个设计进行再重构。既然所有的车都有动力系统,而且每个动力系统的接口都可以是一样的,那我们就把这个动力系统提取出来作为一个单独的类。这也是应用了Bridge模式之后的结果。具体结构图参见图四。

 
                                   图四:应用了Bridge模式之后的重构结果

       JDBC的例子 
网络上看到有朋友对JDBC到底是不是应用了Bridge模式有一些分歧。这一点我们还是很明确的,JDBC确实是应用了Bridge模式。
JDBC其实只是Sun定义出来的一套规范,java.sql下的真正内容大部分都是接口。而其他的数据库厂商则可以分别提供自己的jdbc实现来支持自家的数据库。作为应用开发者,完全可以只靠Sun的这套JDBC接口来完成所有的应用开发,而无需关心数据库是哪一家的。作为数据库厂商,只需要提供自家数据库的实现就可以了,完全不需要考虑自家的数据库会被用来做什么样的应用。这也就是抽象(数据库的应用)和实现(各厂商的JDBC实现)的分离。
再说到代码,想想我们用JDBC写数据库应用时,与具体数据库关联的代码只有一行。

[java] view plaincopy
  1. Class.forName("com.mysql.jdbc.Driver"); // driver name  


       这行代码所做的事情也非常简单,就是创建一个自己(com.mysql.jdbc.Driver)的实例,注册到java.sql.DriverManager中。

[java] view plaincopy
  1. package com.mysql.jdbc;  
  2. import java.sql.DriverManager;  
  3. import java.sql.SQLException;  
  4. public class Driver extends NonRegisteringDriver  
  5.     implements java.sql.Driver  
  6. {  
  7.     static  
  8.     {  
  9.         try  
  10.         {  
  11.             DriverManager.registerDriver(new Driver());  
  12.         } catch (SQLException E) {  
  13.             throw new RuntimeException("Can't register driver!");  
  14.         }  
  15.     }  
  16. }  



之后在调用DriverManager.getConnection()时就会从已注册的driver中寻找合适的项并返回。

简单的一个结构图如图五。
 
                                                     图五:JDBC中Bridge模式的应用

在这里,有一点小小的意外,DriverManager提供了一组静态方法,并且私有化了自己的构造函数。可以简单的认为只有一个实例存在(实际上数据是以类变量的形式存在)。这个看似意外的设计,导致DriverManager不再具备扩展性,但其实是一种更合适的设计,因为我们也不需要n多的DriverManager的实例存在,也不需要它还有任何扩展的可能。
JDBC的Bridge模式其实可以算是Bridge模式的另外一种表现。我们在应用设计时,也要考虑具体的场景和需求,来选用合适的结构,而不能一味的套用。
另外需要说明一下的是,图五只是用了两个类来表示Bridge模式的应用。但在JDBC中,并不仅仅是Driver被抽象出来了,还有Connection,Statement等一组Interface都是被抽象出来的实现。

      适用于 
       ★类的某部分功能会剧烈变化时,把抽象和实现分离,则抽象的部分在开发时不会受到实现部分变动的影响
       ★想要使抽象和实现部分分别开发,互不依赖时
       ★想要避免抽象和实现的强耦合,使实现部分可以在运行时被动态的切换
       ★想要对抽象隐藏实现部分或者对实现隐藏抽象部分时(外包时可用)

     心得总结 
Bridge模式所应用的核心设计思想是针对接口编程,组合优于继承。
从上面的汽车的设计重构过程来看,我们也可以得出这样的结论,如果在抽取类的时候就严格按照CRC的原则进行的话,那么动力系统是很容易被抽取成一个单独的类,并且作为汽车的一个组成部分而存在。当然,Car和Engine之间只能是聚合关系,而不是组合关系,因为Engine完全可以独立存在,或者安装到其他的机械设备上。

参考资料 
1. 软件设计 Bridge模式(新的理解,新的参考)
   http://humingke1984.blog.163.com/blog/static/34777159201062444653948/
2. 从桥接模式与策略模式谈起
   http://www.blogjava.net/wangle/archive/2007/04/25/113545.html
3. Bridge模式学习笔记
   http://blog.csdn.net/zjibo/archive/2009/09/10/4540030.aspx
4. 再论桥接模式(上)纸上谈兵
   http://blog.csdn.net/jyk/archive/2009/12/04/4936430.aspx
5. Bridge模式,Decorator模式(转载)
   http://www.360doc.com/content/08/0801/15/63912_1497477.shtml

来源:http://blog.csdn.net/superbeck/article/details/5969884

分享到:
评论

相关推荐

    Bridge 桥接模式

    C#面向对象设计模式 Bridge 桥接模式 视频讲座下载

    C#面向对象设计模式纵横谈(8):Bridge 桥接模式(结构型模式)

    在C#中,面向对象设计模式通常用于解决复杂度问题,桥接模式则是一种更为高级的设计策略。它通过引入一个抽象接口,将抽象类与其具体实现分离开来,形成两个独立的继承层次,这样抽象部分和实现部分都可以独立地进行...

    设计模式之桥接模式BridgePattern

    桥接模式(Bridge Pattern)是设计模式中的一种结构型模式,它主要解决的是在软件设计中,当抽象和实现之间存在紧密耦合时,如何使这两者能够独立地变化。这种模式通过引入一个抽象层来分离接口和实现,使得它们可以...

    Bridge 桥接模式(结构型模式)

    桥接模式(Bridge Pattern)是一种结构型设计模式,它的主要目的是将抽象部分与实现部分分离,使得它们可以独立地进行变化。在软件工程中,这种分离有助于降低复杂性,提高代码的可维护性和可扩展性。桥接模式的核心...

    C#面向对象设计模式纵横谈\8 结构型模式Bridge桥接模式.zip

    在这里与各位分享本人从网络上下载的C#面向对象设计模式纵横谈系列视频,共有25节,除了第一节需要各位贡献一点资源分以作为对本人上传资源的回馈,后面的其他资源均不需要资源... 这是第8节:结构型模式Bridge桥接模式

    C#面向对象设计模式纵横谈(8):Bridge 桥接模式(结构型模式) (Level 300)

    桥接模式(Bridge Pattern)是一种结构型设计模式,它旨在将抽象部分与其实现部分分离,使得它们可以独立地进行变化。在C#编程中,这种模式尤其有用,因为随着软件系统的复杂性增加,类的继承层次可能会变得难以管理...

    c++-设计模式之桥接模式(Bridge Pattern)

    桥接模式(Bridge Pattern)是一种结构型设计模式,它将抽象部分与实现部分分离,使得两者可以独立地变化。这种模式常用于需要在多个维度上变化的场景,比如不同的形状和颜色,允许在不改变客户端代码的情况下增加新...

    设计模式---桥接模式

    桥接模式是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立进行变化。这种模式在软件工程中被广泛应用于处理组件之间的耦合问题,特别是当需要为同一抽象提供多种实现或者需要独立地改变它们时。 ...

    设计模式之桥接模式,内含可运行代码

    桥接模式是软件设计模式中的一种结构型模式,它的主要目的是为了实现抽象和实现的解耦,使得两者可以独立地进行扩展。在桥接模式中,抽象类(Abstraction)不直接引用具体实现(Implementation),而是通过一个桥接...

    设计模式之桥接模式

    桥接模式(Bridge Pattern)是设计模式中结构型模式的一种,它的主要目的是将抽象部分与实现部分解耦,使得它们可以独立地进行变化。在Java编程中,这种模式的应用可以帮助我们构建更加灵活、可扩展的代码结构。 ...

    设计模式的桥接模式的例子

    桥接模式是设计模式中的一种结构型模式,它旨在将抽象部分与实现部分解耦,使得它们可以独立地变化。这种模式将抽象类和它的实现类进行分离,通过一个抽象接口来连接它们,使得两者可以独立发展,增加了系统的灵活性...

    设计模式面面观(10):桥接模式(Bridge Pattern)-结构型模式

    创建型模式 (100%) 设计模式面面观(8):创建型模式总结 (100%) 设计模式面面观(9):适配器模式(Adapter Pattern)-结构型模式 (100%) 设计模式面面观(10):桥接模式(Bridge Pattern)-结构型模式 ...

    结构型模式之桥接模式(bridge)

    桥接模式是设计模式中的一种结构型模式,其主要目的是为了分离抽象部分和实现部分,以便两者能够独立地进行变化。这种模式的核心理念是通过引入一个抽象层来封装多种可能的实现,使得抽象和实现之间形成一种“桥接”...

    C++设计模式之桥接模式(Bridge)

    C++设计模式之桥接模式(Bridge) 桥接模式(Bridge)是一种结构型设计模式,它的主要作用是将抽象部分与实现部分分离,使它们可以独立地变化。这使得系统更加灵活、可扩展和易于维护。 桥接模式的定义 桥接模式...

    设计模式之桥接模式.pdf

    ### 设计模式之桥接模式详解 #### 一、桥接模式概述 桥接模式(Bridge Pattern)是一种常用的结构型设计模式,它主要用于解决抽象部分和实现部分的耦合问题。这种模式通过将抽象和实现分离,使得两者可以独立变化...

    BridgePattern 桥接设计模式示例

    桥接设计模式是一种结构型设计模式,它将抽象部分与其实现部分相分离,使得它们可以独立进行变化。在实际的软件开发中,这种模式能够帮助我们构建灵活、可扩展的系统,允许我们在不修改原有代码的情况下增加新的功能...

    桥接模式和策略模式的区别,内含可运行代码和两者详细区别

    桥接模式和策略模式是软件设计模式中的两种重要模式,它们在实现上有着相似之处,但各自的应用场景和设计理念有所不同。下面将详细阐述这两种模式的特点、区别以及它们在实际编程中的应用。 首先,桥接模式(Bridge...

    Bridge 桥接

    桥接模式(Bridge Pattern)是一种结构型设计模式,它的主要目的是将抽象部分与实现部分分离,使得它们可以独立地进行变化。在这个例子中,我们将会深入探讨桥接模式的概念、结构以及它在实际开发中的应用。 桥接...

Global site tag (gtag.js) - Google Analytics