`
chjavach
  • 浏览: 460956 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

研磨设计模式之桥接模式-4

阅读更多

3.4  广义桥接-Java中无处不桥接

        使用Java编写程序,一个很重要的原则就是“面向接口编程”,说得准确点应该是“面向抽象编程”,由于在Java开发中,更多的使用接口而非抽象类,因此通常就说成“面向接口编程”了。
        接口把具体的实现和使用接口的客户程序分离开来,从而使得具体的实现和使用接口的客户程序可以分别扩展,而不会相互影响。使用接口的程序结构如图12所示:


                          图12  使用接口的程序结构示意图


        可能有些朋友会觉得,听起来怎么像是桥接模式的功能呢?没错,如果把桥接模式的抽象部分先稍稍简化一下,暂时不要RefinedAbstraction部分,那么就跟上面的结构图差不多了。去掉RefinedAbstraction后的简化的桥接模式结构示意图如图13所示:


                图13  简化的桥接模式结构示意图


        是不是差不多呢?有朋友可能会觉得还是有很大差异,差异主要在:前面接口的客户程序是直接使用接口对象,不像桥接模式的抽象部分那样,是持有具体实现部分的接口,这就导致画出来的结构图,一个是依赖,一个是聚合关联。
        请思考它们的本质功能,桥接模式中的抽象部分持有具体实现部分的接口,最终目的是什么,还不是需要通过调用具体实现部分的接口中的方法,来完成一定的功能,这跟直接使用接口没有什么不同,只是表现形式有点不一样。再说,前面那个使用接口的客户程序也可以持有相应的接口对象,这样从形式上就一样了。
        也就是说,从某个角度来讲,桥接模式不过就是对“面向抽象编程”这个设计原则的扩展。正是通过具体实现的接口,把抽象部分和具体的实现分离开来,抽象部分相当于是使用实现部分接口的客户程序,这样抽象部分和实现部分就松散耦合了,从而可以实现相互独立的变化。
        这样一来,几乎可以把所有面向抽象编写的程序,都视作是桥接模式的体现,至少算是简化的桥接模式,就算是广义的桥接吧。而Java编程很强调“面向抽象编程”,因此,广义的桥接,在Java中可以说是无处不在。
        再举个大家最熟悉的例子来示例一下。在Java应用开发中,分层实现算是最基本的设计方式了吧,就拿大家最熟的三层架构来说,表现层、逻辑层和数据层,或许有些朋友对它们称呼的名称不同,但都是同一回事情。
三层的基本关系是表现层调用逻辑层,逻辑层调用数据层,通过什么来进行调用呢?当然是接口了,它们的基本结构如图14所示:


           图14  基本的三层架构示意图


        通过接口来进行调用,使得表现层和逻辑层分离开来,也就是说表现层的变化,不会影响到逻辑层,同理逻辑层的变化不会影响到表现层。这也是同一套逻辑层和数据层,就能够同时支持不同的表现层实现的原因,比如支持Swing或Web方式的表现层。
        在逻辑层和数据层之间也是通过接口来调用,同样使得逻辑层和数据层分离开,使得它们可以独立的扩展。尤其是数据层,可能会有很多的实现方式,比如:数据库实现、文件实现等,就算是数据库实现,又有针对不同数据库的实现,如Oracle、DB2等等。
        总之,通过面向抽象编程,三层架构的各层都能够独立的扩展和变化,而不会对其它层次产生影响。这正好是桥接模式的功能,实现抽象和实现的分离,从而使得它们可以独立的变化。当然三层架构不只是在一个地方使用桥接模式,而是至少在两个地方来使用了桥接模式,一个在表现层和逻辑层之间,一个在逻辑层和数据层之间。
        下面先分别看看这两个使用桥接模式的地方的程序结构,然后再综合起来看看整体的程序结构。先看看逻辑层和数据层之间的程序结构,如图15所示:


              图15  逻辑层和数据层的程序结构示意图


 再看看表现层和逻辑层之间的结构示意,如图16所示:


      图16  表现层和逻辑层的结构示意图


 然后再把它们结合起来,看看结合后的程序结构,如图17所示:


                             图17  三层结合的结构示意图


        从广义桥接模式的角度来看,平日熟悉的三层架构其实就是在组合使用桥接模式。从这个图还可以看出,桥接模式是可以连续组合使用的,一个桥接模式的实现部分,可以作为下一个桥接模式的抽象部分。如此类推,可以从三层架构扩展到四层、五层、直到N层架构,都可以使用桥接模式来组合。
        如果从更本质的角度来看,基本上只要是面向抽象编写的Java程序,都可以视为是桥接模式的应用,都是让抽象和实现相分离,从而使它们能独立的变化。不过只要分离的目的达到了,叫不叫桥接模式就无所谓了。


3.5  桥接模式的优缺点

  • 分离抽象和实现部分
        桥接模式分离了抽象和实现部分,从而极大地提高了系统的灵活性。让抽象部分和实现部分独立开来,分别定义接口,这有助于对系统进行分层,从而产生更好的结构化的系统。对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了。
  • 更好的扩展性
        由于桥接模式把抽象和实现部分分离开了,而且分别定义接口,这就使得抽象部分和实现部分可以分别独立的扩展,而不会相互影响,从而大大的提高了系统的可扩展性。
  • 可动态切换实现
        由于桥接模式把抽象和实现部分分离开了,那么在实现桥接的时候,就可以实现动态的选择和使用具体的实现,也就是说一个实现不再是固定的绑定在一个抽象接口上了,可以实现运行期间动态的切换实现。
  • 可减少子类的个数
        根据前面的讲述,对于有两个变化纬度的情况,如果采用继承的实现方式,大约需要两个纬度上的可变化数量的乘积个子类;而采用桥接模式来实现的话,大约需要两个纬度上的可变化数量的和个子类。可以明显地减少子类的个数。


3.6  思考桥接模式

1:桥接模式的本质
        桥接模式的本质:分离抽象和实现
        桥接模式最重要的工作就是分离抽象部分和实现部分,这是解决问题的关键。只有把抽象和实现分离开了,才能够让它们可以独立的变化;只有抽象和实现可以独立的变化,系统才会有更好的可扩展性、可维护性。
        至于其它的好处,比如:可以动态切换实现、可以减少子类个数等。都是把抽象部分和实现部分分离过后,带来的,如果不把抽象部分和实现部分分离开,那就一切免谈了。所以综合来说,桥接模式的本质在于“分离抽象和实现”。


2:对设计原则的体现
(1)桥接模式很好的实现了开闭原则。
        通常应用桥接模式的地方,抽象部分和实现部分都是可变化的,也就是应用会有两个变化纬度,桥接模式就是找到这两个变化,并分别封装起来,从而合理的实现OCP。
        在使用桥接模式的时候,通常情况下,顶层的Abstraction和Implementor是不变的,而具体的Implementor的实现,是可变的,由于Abstraction是通过接口来操作具体的实现,因此具体的Implementor的实现是可以扩展的,根据需要可以有多个具体的实现。
        同样的,RefinedAbstraction也是可变的,它继承并扩展Abstraction,通常在RefinedAbstraction的实现里面,会调用Abstraction中的方法,通过组合使用来完成更多的功能,这些功能常常是与具体业务有关系的功能。
        桥接模式还很好的体现了:多用对象组合,少用对象继承。
        在前面的示例中,如果使用对象继承来扩展功能,不但让对象之间有很强的耦合性,而且会需要很多的子类才能完成相应的功能,前面已经讲述过了,需要两个纬度上的可变化数量的乘积个子类。
        而采用对象的组合,松散了对象之间的耦合性,不但使每个对象变得简单和可维护,还大大减少了子类的个数,根据前面的讲述,大约需要两个纬度上的可变化数量的和这么多个子类。


3:何时选用桥接模式
        建议在如下情况中,选用桥接模式:

  • 如果你不希望在抽象和实现部分采用固定的绑定关系,可以采用桥接模式,来把抽象和实现部分分开,然后在程序运行期间来动态的设置抽象部分需要用到的具体的实现,还可以动态切换具体的实现。
  • 如果出现抽象部分和实现部分都应该可以扩展的情况,可以采用桥接模式,让抽象部分和实现部分可以独立的变化,从而可以灵活的进行单独扩展,而不是搅在一起,扩展一边会影响到另一边。
  • 如果希望实现部分的修改,不会对客户产生影响,可以采用桥接模式,客户是面向抽象的接口在运行,实现部分的修改,可以独立于抽象部分,也就不会对客户产生影响了,也可以说对客户是透明的。
  • 如果采用继承的实现方案,会导致产生很多子类,对于这种情况,可以考虑采用桥接模式,分析功能变化的原因,看看是否能分离成不同的纬度,然后通过桥接模式来分离它们,从而减少子类的数目。

 

3.7  相关模式

  • 桥接模式和策略模式
        这两个模式有很大的相似之处。
        如果把桥接模式的抽象部分简化来看,如果暂时不去扩展Abstraction,也就是去掉RefinedAbstraction。桥接模式简化过后的结构图参见图13。再看策略模式的结构图参见图17.1。会发现,这个时候它们的结构都类似如图18所示:


                                    图18  桥接模式和策略模式结构示意图
        通过上面的结构图,可以体会到桥接模式和策略模式是如此相似。可以把策略模式的Context视做是使用接口的对象,而Strategy就是某个接口了,具体的策略实现那就相当于接口的具体实现。这样看来的话,某些情况下,可以使用桥接模式来模拟实现策略模式的功能。
        这两个模式虽然相似,也还是有区别的。最主要的是模式的目的不一样,策略模式的目的是封装一系列的算法,使得这些算法可以相互替换;而桥接模式的目的是分离抽象和实现部分,使得它们可以独立的变化。
  • 桥接模式和状态模式
        由于从模式结构上看,状态模式和策略模式是一样的,这两个模式的关系也基本上类似于桥接模式和策略模式的关系。
        只不过状态模式的目的是封装状态对应的行为,并在内部状态改变的时候改变对象的行为。
  • 桥接模式和模板方法模式
        这两个模式有相似之处。
        虽然标准的模板方法模式是采用继承来实现的,但是模板方法也可以通过回调接口的方式来实现,如果把接口的实现独立出去,那就类似于模板方法通过接口去调用具体的实现方法了。这样的结构就和简化的桥接模式类似了。
        可以使用桥接模式来模拟实现模板方法模式的功能。如果在实现Abstraction对象的时候,在里面定义方法,方法里面就是某个固定的算法骨架,也就是说这个方法就相当于模板方法。在模板方法模式里,是把不能确定实现的步骤延迟到子类去实现;现在在桥接模式里面,把不能确定实现的步骤委托给具体实现部分去完成,通过回调实现部分的接口,来完成算法骨架中的某些步骤。这样一来,就可以实现使用桥接模式来模拟实现模板方法模式的功能了。
        使用桥接模式来模拟实现模板方法模式的功能,还有个潜在的好处,就是模板方法也可以很方便的扩展和变化了。在标准的模板方法里面,一个问题就是当模板发生变化的时候,所有的子类都要变化,非常不方便。而使用桥接模式来实现类似的功能,就没有这个问题了。
        另外,这里只是说从实现具体的业务功能上,桥接模式可以模拟实现出模板方法模式能实现的功能,并不是说桥接模式和模板方法模式就变成一样的,或者是桥接模式就可以替换掉模板方法模式了。要注意它们本身的功能、目的、本质思想都是不一样的。
  • 桥接模式和抽象工厂模式
        这两个模式可以组合使用。
        桥接模式中,抽象部分需要获取相应的实现部分的接口对象,那么谁来创建实现部分的具体实现对象呢?这就是抽象工厂模式派上用场的地方。也就是使用抽象工厂模式来创建和配置一个特定的具体实现的对象。
        事实上,抽象工厂主要是用来创建一系列对象的,如果创建的对象很少,或者是很简单,还可以采用简单工厂,可以达到一样的效果,但是会比抽象工厂来得简单。
  • 桥接模式和适配器模式
        这两个模式可以组合使用。
        这两个模式功能是完全不一样的,适配器模式的功能主要是用来帮助无关的类协同工作,重点在解决原本由于接口不兼容而不能一起工作的那些类,使得它们可以一起工作。而桥接模式则重点在分离抽象和实现部分。
        所以在使用上,通常在系统设计完成过后,才会考虑使用适配器模式;而桥接模式,是在系统开始的时候就要考虑使用。
        虽然功能上不一样,这两个模式还是可以组合使用的,比如:已有实现部分的接口,但是有些不太适应现在新的功能对接口的需要,完全抛弃吧,有些功能还用得上,该怎么办呢?那就使用适配器来进行适配,使得旧的接口能够适应新的功能的需要。

 

 研磨设计模式结束,谢谢捧场! 

  • 大小: 3.3 KB
  • 大小: 3.3 KB
  • 大小: 1.3 KB
  • 大小: 4.2 KB
  • 大小: 3 KB
  • 大小: 4.8 KB
  • 大小: 3.2 KB
87
8
分享到:
评论
15 楼 fantasycs 2010-12-23  
写的很好啊!真的了解的很透彻啊!
14 楼 lxy19791111 2010-10-15  
写得很详细,辛苦了,谢谢。。。
13 楼 bbyyzhang 2010-09-27  
经典之作,拜读了
12 楼 yoin528 2010-09-09  
如果有一些事例性的代码块会更完美。
11 楼 116427 2010-09-08  

就等着你的书出版了!

你就是一个传道者,为迷茫的同学指引了一个学习的目标,哈哈。。
10 楼 chjavach 2010-09-08  
116427 写道

看了楼主写的一部分文章:

受益匪浅,楼主解释的很好,能把问题说透彻。 

希望楼主把这个系列坚持写下去,另外再补充点:

1.在讲解单个独立的设计模式的基础上再从大方面总结一下,比如从建造者模式,行为模式

等分类入手。

2.结合目前使用比较广泛的实例,说一下模式的应用,比如,spring,hibernate等在设

计时所主要采用的模式。

如果再能举一个比较完整的真实项目例子综合运用一下多个模式,那就更完美了!

总之,非常钦佩楼主的设计能力以及钻研,分享的精神!  


  会继续努力的,正在准备用一个真实可用的项目,综合应用GoF提到的23个设计模式。而且这个项目不能太大,太大了很难看完,也很难完全看懂,目前的设计是在实现功能的前提下,刚刚好把这些模式都综合应用进去,这样更利于大家学习和参考。
   PS:这个项目是实际可用的,基本上大家都可能会用得上,准备做完了捐献给开源界,呵呵
9 楼 okhaoba 2010-09-07  
一口气1234看完了,受教了。
8 楼 nature_park 2010-09-07  
楼主讲的真的是很好,但是我却从来没有在项目中用过这些模式,有点郁闷
7 楼 lcllcl987 2010-09-06  
    这两个模式虽然相似,也还是有区别的。最主要的是模式的目的不一样,策略模式的目的是封装一系列的算法,使得这些算法可以相互替换;而桥接模式的目的是分离抽象和实现部分,使得它们可以独立的变化。
---------------------------------
广义上来说,interface的存在都是为了“分离抽象和实现”
对于桥接模式, 我的理解是:分离抽象和行为, 而不是“分离抽象和实现”。
楼主的发送消息的例子很经典。
两个维度的变化,一个维度是“抽象对象:消息“的抽象和扩展, 一个维度是“行为:发送方式”的抽象和扩展。
6 楼 superheizai 2010-09-06  
,确实不像现在很多都是浅尝辄止的设计模式的书,研磨系列,更深入,更具体!
估计楼主这么长时间没更新,肯定受出版社邀约了吧,呵呵。
5 楼 116427 2010-09-06  

看了楼主写的一部分文章:

受益匪浅,楼主解释的很好,能把问题说透彻。 

希望楼主把这个系列坚持写下去,另外再补充点:

1.在讲解单个独立的设计模式的基础上再从大方面总结一下,比如从建造者模式,行为模式

等分类入手。

2.结合目前使用比较广泛的实例,说一下模式的应用,比如,spring,hibernate等在设

计时所主要采用的模式。

如果再能举一个比较完整的真实项目例子综合运用一下多个模式,那就更完美了!

总之,非常钦佩楼主的设计能力以及钻研,分享的精神!  
4 楼 po_534 2010-09-06  
楼主对广义桥接模式的阐述,对我而言,只能用震撼来形容,从来就没有这样想过,但经楼主讲出来,确实又是这样,楼主对模式的理解实在是太深刻了,超赞
3 楼 zistrong 2010-09-06  
LZ终于更新了,持续关注!
2 楼 lwp2000 2010-09-06  
LZ终于出新博了! 看来最近很忙呀!大家都在等你下文呢!努力呀!
1 楼 rather_lonely 2010-09-06  
来看楼主的更新了

相关推荐

    研磨设计模式之桥接模式

    来写一个大家既陌生又熟悉的设计模式,也是非常实用的一个设计模式,那就是桥接模式。说陌生是很多朋友并不熟悉这个设计模式,说熟悉是很多人经常见到或者是下意识的用到这个设计模式,只是不知道罢了。桥接模式是...

    研磨设计模式(完整带书签).part2.pdf

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式--chjavach的博客文章

    单例模式、工厂方法模式、策略模式、命令模式和桥接模式。

    研磨设计模式(完整带书签).part1.pdf

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式-part4

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式-part2

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式-part3

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式.part4(共4个)

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式.docx

    研磨设计模式系列,包括: 单例模式、工厂方法模式、策略模式、命令模式和桥接模式

    研磨设计模式.part3(共4个)

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式.part2(共4个)

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式.part1(共4个)

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

Global site tag (gtag.js) - Google Analytics