《Java设计模式》之桥接模式

Bridge模式的概念

Bridge 模式是构造型的设计模式之中的一个。Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而能够保持各部分的独立性以及应对它们的功能扩展。

Bridge模式的应用场景

面向对象的程序设计(OOP)里有类继承(子类继承父类)的概念,假设一个类或接口有多个详细实现子类。假设这些子类具有下面特性:
- 存在相对并列的子类属性。
- 存在概念上的交叉。
- 可变性。
我们就能够用Bridge模式来对其进行抽象与详细。对相关类进行重构。

桥接模式的适用:

你不希望在抽象和它的实现部分之间有一个固定的绑定关系。比如:程序的实现部分在执行时须要被选择或者切换。

类的抽象以及它的实现都应该能够通过生成子类的方法加以扩充。

这时Bridge模式使你能够对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。

对一个抽象实现的改动须要对客户不产生影响,即客户的代码不必又一次编译。

有很多类要生成。这样的情况下你必须将一个对象分解成两个部分。这样的类层次结构为“嵌套的普化”。

你想在多个对象间共享实现(可能使用引用计数),但同一时候要求客户并不知道这一点。


生活中的一个样例:
    拿汽车在路上行驶的来说。

既有小汽车又有公共汽车,它们都不但能在市区中的公路上行驶,也能在快速公路上行驶。这你会发现,对于交通工具(汽车)有不同的类型。它们所行驶的环境(路)也有不同类型,在软件系统中就要适应两个方面(不同车型,不同道路)的变化,如何实现才干应对这样的变化呢?
概述:
在软件系统中。某些类型因为自身的逻辑。它具有两个或多个维度的变化,那么怎样应对这样的“多维度的变化”?怎样利用面向对象的技术来使得该类型可以轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式。


意图:
   将抽象部分与实现部分分离,使它们都能够独立的变化。
                                                                    ——《设计模式》GOF 

上面这些话我也没看懂。

。太抽象了,可是一看代码你就明确是怎么回事了。
结构图:

传统的做法:
        通过类继承的方式来做上面的样例;

先看一下类结构图:

代码实现:

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1.         //基类 路  
  2. class Road {  
  3.     void run() {  
  4.         System.out.println("路");  
  5.     }  
  6. }  
  7.   
  8. //市区街道  
  9. class Street extends Road {  
  10.     void run() {  
  11.         System.out.println("市区街道");  
  12.     }  
  13. }  
  14.   
  15. //快速公路  
  16. class SpeedWay extends Road {  
  17.     void run() {  
  18.         System.out.println("快速公路");  
  19.     }  
  20. }  
  21. //小汽车在市区街道行驶  
  22. class CarOnStreet extends Street {  
  23.     void run() {  
  24.         System.out.println("小汽车在市区街道行驶");  
  25.     }  
  26. }  
  27. //小汽车在快速公路行驶  
  28. class CarOnSpeedWay extends SpeedWay {  
  29.     void run() {  
  30.         System.out.println("小汽车在快速公路行驶");  
  31.     }  
  32. }  
  33. //公交车在市区街道行驶  
  34. class BusOnStreet extends Street {  
  35.     void run() {  
  36.         System.out.println("公交车在市区街道行驶");  
  37.     }  
  38. }  
  39. //公交车在快速公路行驶  
  40. class BusOnSpeedWay extends SpeedWay {  
  41.     void run() {  
  42.         System.out.println("公交车在快速公路行驶");  
  43.     }  
  44. }  
  45. //測试  
  46. public static void main(String[] args) {  
  47.       
  48.     //小汽车在快速公路行驶  
  49.     CarOnSpeedWay carOnSpeedWay = new CarOnSpeedWay();  
  50.     carOnSpeedWay.run();  
  51.     //公交车在市区街道行驶  
  52.     BusOnStreet busOnStreet = new BusOnStreet();  
  53.     busOnStreet.run();  
  54.   
  55. }  

缺点:
     可是我们说这种设计是脆弱的,细致分析就能够发现,它还是存在非常多问题,首先它在遵循开放-封闭原则的同一时候。违背了类的单一职责原则,即一个类仅仅有一个引起它变化的原因。而这里引起变化的原因却有两个。即路类型的变化和汽车类型的变化;其次是反复代码会非常多,不同的汽车在不同的路上行驶也会有一部分的代码是同样的;

再次是类的结构过于复杂,继承关系太多,难于维护。最后最致命的一点是扩展性太差。假设变化沿着汽车的类型和不同的道路两个方向变化,我们会看到这个类的结构会迅速的变庞大。

应用设计模式
       桥接模式(Bridge)来做;

先看一下类结构图:

代码实现:

[java] view plaincopyprint?

在CODE上查看代码片派生到我的代码片
  1. abstract class AbstractRoad{  
  2.     AbstractCar aCar;  
  3.     void run(){};  
  4. }  
  5. abstract class AbstractCar{  
  6.     void run(){};  
  7. }  
  8.   
  9. class Street extends AbstractRoad{  
  10.     @Override  
  11.     void run() {  
  12.         // TODO Auto-generated method stub  
  13.         super.run();  
  14.         aCar.run();  
  15.         System.out.println("在市区街道行驶");  
  16.     }  
  17. }  
  18. class SpeedWay extends AbstractRoad{  
  19.     @Override  
  20.     void run() {  
  21.         // TODO Auto-generated method stub  
  22.         super.run();  
  23.         aCar.run();  
  24.         System.out.println("在快速公路行驶");  
  25.     }  
  26. }  
  27. class Car extends AbstractCar{  
  28.     @Override  
  29.     void run() {  
  30.         // TODO Auto-generated method stub  
  31.         super.run();  
  32.         System.out.print("小汽车");  
  33.     }  
  34. }  
  35. class Bus extends AbstractCar{  
  36.     @Override  
  37.     void run() {  
  38.         // TODO Auto-generated method stub  
  39.         super.run();  
  40.         System.out.print("公交车");  
  41.     }  
  42. }  
  43.   
  44. public static void main(String[] args){  
  45.       
  46.     AbstractRoad speedWay = new SpeedWay();  
  47.     speedWay.aCar = new Car();  
  48.     speedWay.run();  
  49.       
  50.     AbstractRoad street = new Street();  
  51.     street.aCar = new Bus();  
  52.     street.run();  
  53. }  

 能够看到。通过对象组合的方式,Bridge 模式把两个角色之间的继承关系改为了耦合的关系。从而使这两者能够从容自若的各自独立的变化,这也是Bridge模式的本意。
      这样添加了客户程序与路与汽车的耦合。

事实上这种操心是没有必要的,由于这种耦合性是由于对象的创建所带来的,全然能够用创建型模式去解决。在应用时结合创建型设计模式来处理详细的问题。


应用设计模式:
       桥接模式(Bridge)来做(
多维度变化);
       结合上面的样例,添加一个维度"人",不同的人开着不同的汽车在不同的路上行驶(三个维度);
       结合上面添加一个类"人",并又一次调用.
代码实现:

[java] view plaincopyprint?

在CODE上查看代码片派生到我的代码片
  1. abstract class People {  
  2.     AbstractRoad road;  
  3.   
  4.     void run() {}  
  5. }  
  6.   
  7. class Man extends People{  
  8.     @Override  
  9.     void run() {  
  10.         // TODO Auto-generated method stub  
  11.         super.run();  
  12.         System.out.print("男人开着");  
  13.         road.run();  
  14.     }  
  15. }  
  16. class Woman extends People{  
  17.     @Override  
  18.     void run() {  
  19.         // TODO Auto-generated method stub  
  20.         super.run();  
  21.         System.out.print("女人开着");  
  22.         road.run();  
  23.     }  
  24. }  
  25.   
  26. public static void main(String[] args) {  
  27.   
  28.     AbstractRoad speedWay = new SpeedWay();  
  29.     speedWay.aCar = new Car();  
  30.       
  31.     People man = new Man();  
  32.     man.road = speedWay;  
  33.     man.run();  
  34. }  


效果及实现要点:
1.Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现能够沿着各自的维度来变化。


2.所谓抽象和实现沿着各自维度的变化,即“子类化”它们。得到各个子类之后,便能够随意它们。从而获得不同路上的不同汽车。
3.Bridge模式有时候类似于多继承方案,可是多继承方案往往违背了类的单一职责原则(即一个类仅仅有一个变化的原因),复用性比較差。Bridge模式是比多继承方案更好的解决方法。


4.Bridge模式的应用一般在“两个很强的变化维度”,有时候即使有两个变化的维度。可是某个方向的变化维度并不剧烈——换言之两个变化不会导致纵横交错的结果,并不一定要使用Bridge模式。

适用性:
   在下面的情况下应当使用桥梁模式:
1.假设一个系统须要在构件的抽象化角色和详细化角色之间添加很多其它的灵活性,避免在两个层次之间建立静态的联系。 
2.设计要求实现化角色的不论什么改变不应当影响client,或者说实现化角色的改变对client是全然透明的。
3.一个构件有多于一个的抽象化角色和实现化角色。系统须要它们之间进行动态耦合。 
4.尽管在系统中使用继承是没有问题的。可是因为抽象化角色和详细化角色须要独立变化,设计要求须要独立管理这两者。
总结:
      Bridge模式是一个很实用的模式,也很复杂。它很好的符合了开放-封闭原则和优先使用对象,而不是继承这两个面向对象原则。

 


本文借鉴文章:

http://blog.csdn.net/jason0539/article/details/22568865

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/541246.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java Formatter locale()方法与示例

Formatter类的locale()方法 (Formatter Class locale() method) locale() method is available in java.util package. locale()方法在java.util包中可用。 locale() method is used to returns the locales assign by the construction of this Formatter. locale()方法用于返…

cad中tk什么意思_设计中的“Neobject”什么意思?来了解一下

DesignArchitectureInteriorsFashionArtTransportTHE STUFF THAT REFINES YOU破界造物New Language?“Neobject,言如其字,从语义上,前缀 neo- 表示新的,object 则是物体,是客观存在,很中性,作动…

html文段源码,HTML 段落

HTML 段落HTML 可以将文档分割为若干段落。HTML 段落段落是通过 标签定义的。实例这是一个段落这是另一个段落尝试一下 注意:浏览器会自动地在段落的前后添加空行。( 是块级元素)不要忘记结束标签即使忘了使用结束标签,大多数浏览器也会正确地将 HTML 显…

Python基础语法学习整理

1、基础 r’ ‘:原始字符串 pow、round是内建函数 2、序列通用操作: 索引:d[] 分片:[:] 相加:d[] 乘法:[1,2]*3 成员判断:in 可用函数:len max min 3、列表 删除:del …

Java Collections copy()方法与示例

集合类的copy()方法 (Collections Class copy() method) copy() method is available in java.util package. copy()方法在java.util包中可用。 copy() method is used to copy all the elements from List the src_list (source list) and place all the copied elements into…

c#如何实现叫号操作_微信预约排队叫号系统操作指南

“微信排队预约"功能是阿拉善盟税务局为进一步优化营商环境,深化“放管服”改革,提高纳税便利度,更好地服务于阿拉善经济社会发展而开发的一项便民措施。通过“微信排队预约”功能,纳税人可以随时随地通过微信获取办税大厅的…

计算机用户越权操作的原因,“三员系统”中常见的越权问题

原标题:“三员系统”中常见的越权问题一、越权访问越权访问(Broken Access Control,简称BAC)是Web应用程序中一种常见的漏洞,由于其存在范围广、危害大,被OWASP列为Web应用十大安全隐患的第二名。1.1越权访问的产生比如&#xff0…

富士施乐2022网络扫描设置_富士施乐(FUJI XEROX)全系列复印机产品介绍

富士施乐(FUJI XEROX)复印机全系列详解富士施乐复印机是中小型办公环境的理想机型。所有的都拥有高效生产力和强大的稳定性,无论您需要亮丽色彩、黑白打印、亦或是足以应对复杂文档工作流的强大功能,总有一款适合您。DocuCentre S2110NDocuCentre S2110N…

ruby hash方法_Ruby中带有示例的Hash.rassoc(obj)方法

ruby hash方法Hash.rassoc(obj)方法 (Hash.rassoc(obj) Method) In this article, we will study about Hash.rassoc(obj) Method. The working of the method can’t be assumed because of it’s quite a different name. Let us read its definition and understand its imp…

JavaMail(四):接收邮件

2019独角兽企业重金招聘Python工程师标准>>> 接收邮件采用POP3协议进行接收,简单的一个接收邮件案例如下 /*** 接收邮件*/ public static void receive() throws Exception { // 准备连接服务器的会话信息 Properties props new Properties(); props.se…

html流动海报css,海报网css代码怎样把模块移到右面?最好把代码直接给我!嘿嘿。...

匿名用户13级2010-09-15 回答CSS是Cascading style Sheets的简称,中文译作“层叠样式表单”. 实际上它是一组样式。你可能对CSS这个名词比较陌生,实际上无论你用Internet Explorer还是Netscape Navigator在网上冲浪,几乎随时都在与CSS打交道&…

奥鹏东北大学作业答案计算机网络,东北大学17秋学期《计算机网络》在线作业1参考答案...

一、单选题:【15道,总分:75分】东北大学1.IP地址0.0.0.0表示( )。 (满分:5)A. 广播B. 有限广播C. 自环地址D. 本机2.IP协议中,如果首部不含选项字段,则首部长度字段的值应为( )。 (满分:5)A. 0B. 5C. 10D. 203.滑动窗口的作用是…

append生成新变量的时候,没有如预期(It's a feature,not a bug?)

这是我在写一个项目中,遇到的一个golang的feature,如代码所示,我在for循环里,每次用append生成一个新的数组,(当然我以前一直以为可以这样,直到我在stackoverflow上发现不能。)然后将…

jqgrid本地数据例子_办公系统私有云公有云和本地化部署,你选哪个?

随着互联网和云计算技术的发展,我们常常会听到:私有云、公有云和本地化部署,它们分别代表什么意思?无论是国企、民企还是外企,只要有数据,就要思考:到底将数据储存在哪里?选择轻流进…

计算机基础应用的培养活动记录,小学少年宫计算机兴趣小组活动记录表

小学少年宫计算机兴趣小组活动记录表 小学少年宫计算机兴趣小组活动记录表 活动名称:计算机 指导教师: ⅩⅩ 学生姓名 活动地点 计算机教室 活 动 过 程 活动1.认识计算机 ①师:“请同学们按下方盒子上面像大钮扣一样的按钮&#…

C ++ STL中的set :: lower_bound()函数

C STL set :: lower_bound()函数 (C STL set::lower_bound() function) set::lower_bound() function is a predefined function, it is used to get the lower bound of any element in a set. set :: lower_bound()函数是预定义的函数,用于获取集合中任何元素的下…

flume入门

# example.conf: A single-node Flume configuration# Name the components on this agent #给那三个组件取个名字 a1.sources r1 a1.sinks k1 a1.channels c1# Describe/configure the source #类型, 从网络端口接收数据,在本机启动, 所以localhost, typespoolDir采集目录源…

原生js设置div隐藏或者显示_JavaScript动画方式控制div元素的隐藏和显示

jQuery实现此功能相对比较简单,具体参阅点击按钮动画方式隐藏和显示div一章节。结合CSS3实现此功能也非常便利和适合,具体参阅JavaScript与CSS3动画方式改变元素尺寸一章节。原生JavaScript实现稍显麻烦,下面就通过代码实例介绍一下如何实现此…

python线程任务run_Python线程类| 带有示例的run()方法

python线程任务runPython Thread.run()方法 (Python Thread.run() Method) Thread.run() method is an inbuilt method of the Thread class of the threading module in Python. This method is used to represent a threads activity. It calls the method expressed as the …

哪个计算机无法做到双屏显示,怎么启用双屏显示设置【图文介绍】

随着生活质量的提升,人们对于便利的要求越来越高,电脑的双屏显示成为现在用户越来越关注的对象之一。比如炒股操作中,人们既要关注大盘的走动趋势,又要关注特定股票的走势,在普通的屏幕上就需要不断地切换页面&#xf…