Bridge模式的概念

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

Bridge模式的应用场景

面向对象的程序设计(OOP)里有类继承(子类继承父类)的概念,假设一个类或接口有多个详细实现子类。假设这些子类具有下面特性:

- 存在相对并列的子类属性。

- 存在概念上的交叉。

- 可变性。

我们就能够用Bridge模式来对其进行抽象与详细。对相关类进行重构。

桥接模式的适用:

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

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

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

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

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

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

生活中的一个样例:

    拿汽车在路上行驶的来说。

既有小汽车又有公共汽车,它们都不但能在市区中的公路上行驶,也能在快速公路上行驶。这你会发现,对于交通工具(汽车)有不同的类型。它们所行驶的环境(路)也有不同类型,在软件系统中就要适应两个方面(不同车型,不同道路)的变化,如何实现才干应对这样的变化呢?

概述:

在软件系统中。某些类型因为自身的逻辑。它具有两个或多个维度的变化,那么怎样应对这样的“多维度的变化”?怎样利用面向对象的技术来使得该类型可以轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式。

意图:

   将抽象部分与实现部分分离,使它们都能够独立的变化。

                                                                    ——《设计模式》GOF

上面这些话我也没看懂。

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

结构图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamFzb24wNTM5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" style="border:none; max-width:100%">

传统的做法:

        通过类继承的方式来做上面的样例;

先看一下类结构图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamFzb24wNTM5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" style="border:none; max-width:100%">

代码实现:

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

缺点:

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

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

应用设计模式

       桥接模式(Bridge)来做;

先看一下类结构图:

代码实现:

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

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

      这样添加了客户程序与路与汽车的耦合。

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

应用设计模式:

       桥接模式(Bridge)来做(多维度变化);

       结合上面的样例,添加一个维度"人",不同的人开着不同的汽车在不同的路上行驶(三个维度);

       结合上面添加一个类"人",并又一次调用.

代码实现:

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

效果及实现要点:

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

2.所谓抽象和实现沿着各自维度的变化,即“子类化”它们。得到各个子类之后,便能够随意它们。从而获得不同路上的不同汽车。

3.Bridge模式有时候类似于多继承方案,可是多继承方案往往违背了类的单一职责原则(即一个类仅仅有一个变化的原因),复用性比較差。Bridge模式是比多继承方案更好的解决方法。

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



适用性:

   在下面的情况下应当使用桥梁模式:

1.假设一个系统须要在构件的抽象化角色和详细化角色之间添加很多其它的灵活性,避免在两个层次之间建立静态的联系。 

2.设计要求实现化角色的不论什么改变不应当影响client,或者说实现化角色的改变对client是全然透明的。

3.一个构件有多于一个的抽象化角色和实现化角色。系统须要它们之间进行动态耦合。 

4.尽管在系统中使用继承是没有问题的。可是因为抽象化角色和详细化角色须要独立变化,设计要求须要独立管理这两者。

总结:

      Bridge模式是一个很实用的模式,也很复杂。它很好的符合了开放-封闭原则和优先使用对象,而不是继承这两个面向对象原则。

本文借鉴文章:

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

《Java设计模式》之桥接模式的更多相关文章

  1. java设计模式7——桥接模式

    java设计模式7--桥接模式 1.桥接模式介绍 桥接模式是将抽象部分与它的实现部分分离,使他们都可以独立的变化.它是一种对象结构型模式,又称为柄体模式或接口模式. 2.解决问题 2.1.将复杂的组合 ...

  2. java设计模式之桥接模式

    桥接模式 桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化.这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦.这种模式涉及到一个作为桥接的 ...

  3. Java设计模式:桥接模式

    问题提出 生活中有很多事物集合,设为A1,A2......Am ,而每个事物都有功能F1,F2....Fn. 例如邮局的发送业务.简单模拟有两类事物:信件和包裹,均有平邮和挂号邮寄功能.程序设计中如何 ...

  4. Java设计模式应用——桥接模式

    性能管理系统中,数据产生后需要经过采集,汇聚,入库三个流程,用户才能查询使用. 采集可以是snmp采集,也可以是ems采集:汇聚可以使storm汇聚,也可以是spark汇聚:入库可以是hdfs入库,也 ...

  5. java设计模式之-----桥接模式

    一.概念定义 将抽象部分和实现部分分离,使他们都可以独立的变化.(这句话有点抽象啊..) 在软件系统中,某种类型由于自身逻辑,具有多个维度的变化,如何利用面向对象的技术来使得该类型沿着多方向变化,而又 ...

  6. JAVA设计模式之桥接模式(bridge)

    桥接模式: 分离抽象与具体实现,让他们可以独自发展,防止类爆炸 场景: 过年走亲戚是我们中国人传统的习俗,走亲戚那就少不了要买东西(苹果,牛奶等等),这些具体的东西就是具体的类 蒙牛牛奶,有机苹果,有 ...

  7. 八戒转世投胎竟然是Java设计模式:桥接模式

    目录 示例 代码实例 桥接模式 定义 意图 主要解决问题 何时使用 优缺点 八戒转世投胎的故事 示例 请开发一个画图程序,可以画各种颜色不同形状的图形,请用面向对象的思 想设计图形 分析: 1.比如有 ...

  8. java面试题之----jdbc中使用的设计模式(桥接模式)

    1.JDBC(JavaDatabase Connectivity) JDBC是以统一方式访问数据库的API. 它提供了独立于平台的数据库访问,也就是说,有了JDBC API,我们就不必为访问Oracl ...

  9. Java设计模式——装饰者模式

    JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ...

  10. 浅析JAVA设计模式之工厂模式(一)

    1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...

随机推荐

  1. luoguP1462通往奥格瑞玛的道路(二分答案+spfa)

    题意 给出n个点m条边的无向图. 每条边有两个权值a,b; 问在保证从1到n的路径a权值和小于x时,路径上b权值最大值最小为多少. (n≤10000,m≤50000,x≤1000000000) 题解 ...

  2. caioj 1413 动态规划4:打鼹鼠

    记住一定要区分n和m分别代表什么,我已经因为这个两道题浪费很多时间了 然后这个道题有点类似最长上升子序列n平方的做法,只是判断的条件不同而已 #include<cstdio> #inclu ...

  3. 紫书 例题 10-16 UVa 12230(数学期望)

    感觉数学期望的和化学里面求元素的相对原子质量的算法是一样的 就是同位素的含量乘上质量然后求和得出 这道题因为等待时机是0到2*l/v均匀分配的,所以平均时间就是l/v 再加上过河的l/v, 最后加上步 ...

  4. Hadoop学习总结(1)——大数据以及Hadoop相关概念介绍

    一.大数据的基本概念 1.1.什么是大数据 大数据指的就是要处理的数据是TB级别以上的数据.大数据是以TB级别起步的.在计算机当中,存放到硬盘上面的文件都会占用一定的存储空间,例如: 文件占用的存储空 ...

  5. Apache CXF实战之二 集成Sping与Web容器

    本文链接:http://blog.csdn.net/kongxx/article/details/7525481 Apache CXF实战之一 Hello World Web Service 书接上文 ...

  6. 智课雅思短语---二、exert positive/ negative effects on…

    智课雅思短语---二.exert positive/ negative effects on… 一.总结 一句话总结:对…产生有利/不利的影响 1.the advantages far outweig ...

  7. 35.QQ大数据模型

    #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <stri ...

  8. 推荐的JavaScript编码规范

    http://www.qdfuns.com/notes/26812/7825414125719306fa409c709ee7b2a3.html

  9. windows 手动添加服务

    windows 手动添加服务方法一:修改注册表 在注册表编辑器,展开分支"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services" ...

  10. 安装SQL2008后需要打开的端口为 1433,4630