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. C++输入流

    输出流基本概念  输出流定义在头文件中.大部分程序都会包含头文件,这个头文件又包含了输入流和输出流头文件.头文件还声明了标准控制台输出流cout.  使用输出流的最简单的方法是使用<<运算 ...

  2. spring mvc 防止重复提交表单的两种方法,推荐第二种

    第一种方法:判断session中保存的token 比较麻烦,每次在提交表单时都必须传入上次的token.而且当一个页面使用ajax时,多个表单提交就会有问题. 注解Token代码: package c ...

  3. vmware下ubuntu的网络配置

    捣弄了vmnet0和vmnet8连接后,ubuntu上不了网了,今天突然解决了这个问题. 打开vmware后,点编辑-->虚拟网络编辑器 这里我使用的是NAT模式,所以要修改vmnet8 点vm ...

  4. json的键为变量而不是字符串时,怎么写?

    看栗子 /* 首先你创建了一个window的属性叫b, 并给它赋值为'cccddd' * 然后你创建了一个对象"a", 声明了一个它的属性叫b, 并且给b赋值为6 * 注意第一行的 ...

  5. 智课雅思词汇---四、clos和cap和ced是什么意思

    智课雅思词汇---四.clos和cap和ced是什么意思 一.总结 一句话总结: cap/capt/cip/cep/ceiv:to take,seize(拿,抓住) cede:to go,yield( ...

  6. Gym - 100637B Lunch 规律

    题意:n个点,给定起点和终点,可以每次可以走一格或两格,走一格则需要一个代价,每个格子只能走一次,问从起点到终点并经过每一个点的最小代价 思路:这题我没看出什么道理,先打了个暴力,结果发现了个相当坑的 ...

  7. apache-maven-3.0.4-bin.zip

    http://zhidao.baidu.com/share/2a8974fd1546ef5f11ad9cccb3cabf88.html apache-maven-3.0.4-bin.zip

  8. gcc---C/C++ 编译器

    gcc命令使用GNU推出的基于C/C++的编译器,是开放源代码领域应用最广泛的编译器,具有功能强大,编译代码支持性能优化等特点.现在很多程序员都应用GCC,怎样才能更好的应用GCC.目前,GCC可以用 ...

  9. LRJ入门经典-0905邮票和信封305

    原题 LRJ入门经典-0905邮票和信封305 难度级别:B: 运行时间限制:1000ms: 运行空间限制:256000KB: 代码长度限制:2000000B 试题描述 假定一张信封最多贴5张邮票,如 ...

  10. [Python] Check for None (Null) in Python

    If you’ve used other programming languages, you may have learned that an empty object is not the sam ...