1. 双维度拓展
  2. 实际中用的不多,很少用,了解一下即可
  3. 分离抽象与具体
  4. 用聚合方式(桥)链接抽象与具体
  5. 为了防止类爆炸的问题(见下面gg追mm的例子),采用Bridge的设计模式
  6. 抽象和具体两个维度同时发展,互相之间不影响,也不会产生类爆炸

UML类图

  • 抽象部分的继承树和实现部分的继承树分离开来
  • 但是在抽象中聚合一个具体的实现
  • 两个维度在不同发展,同时发展
  • 用聚合代替继承
    • 聚合到什么中去就代表什么样的什么……

image.png

以GG送不同礼物追MM的过程来说明

GG最初只考虑送花和书当礼物给MM

Gift抽象类

  1. package com.mashibing.dp.bridge.v1;
  2. public abstract class Gift {}

Flower类

  1. package com.mashibing.dp.bridge.v1;
  2. public class Flower extends Gift {
  3. }

Book类

  1. package com.mashibing.dp.bridge.v1;
  2. public class Book extends Gift {
  3. }

MM类

  1. package com.mashibing.dp.bridge.v1;
  2. public class MM {
  3. String name;
  4. }

GG类

  1. package com.mashibing.dp.bridge.v1;
  2. public class GG {
  3. public void chase(MM mm) {
  4. Gift g = new Book();
  5. give(mm, g);
  6. }
  7. public void give(MM mm, Gift g) {
  8. }
  9. }

如果GG考虑将礼物分为温柔的礼物和狂野的礼物 (使用继承)WarmGift WildGift

  • 耦合度高
  • 容易产生类爆炸
  • 如果礼物分为温柔的礼物和狂野的礼物 WarmGift、WildGift,这时Flower应该分为 WarmFlower、WildFlower、WarmBook、WildBook
  • 如果再有别的礼物,比如抽象类型:ToughGift、ColdGift,或者具体的某种实现:Ring、Car ,就会产生类的爆炸WarmCar、ColdRing、WildCar、WildFlower…

    WildGift类

    ```java package com.mashibing.dp.bridge.v2;

public class WildGift extends Gift { }

  1. <a name="xnhug"></a>
  2. #### WarmGift类
  3. ```java
  4. package com.mashibing.dp.bridge.v2;
  5. public class WarmGift extends Gift {
  6. }

WarmFlower类

  1. package com.mashibing.dp.bridge.v3;
  2. /**
  3. * 或者从WarmGift继承
  4. * 或者从Flower继承
  5. */
  6. public class WarmFlower extends Flower {
  7. }
  • 抽象的部分在发展,实现的部分也在发展===>m*n的增长,继承不合适(继承合适就不用设计模式了)
  • 像装饰器模式???只不过装饰的是抽象的而不是具体的
  • 不完美的解决方案:类型都变成interface===>但类型一般变不成interface
    • 因为WarmGift相对有点具体,有自己的抽象方法或者部分实现的方法(不一定是个接口也不一定有接口的含义)

使用桥接模式

  • 双维度拓展
  • 分离抽象与具体
  • 抽象和具体两个维度同时发展,互相之间不影响,也不会产生类爆炸
  • 用聚合方式(桥)链接抽象与具体
  • 使用桥接模式:
    • 分离抽象与具体实现,让他们可以独自发展
    • Gift -> WarmGift、ColdGift、WildGift
    • GiftImpl -> Flower、Ring、Car
  • 桥接模式,抽象类调用某一方法时,实际上是通过成员对象(即具体实现类)调用相应方法实现的
  • 有点像visitor模式,实际上还是多态的灵活运用!

    Gift抽象类

    ```java package com.mashibing.dp.bridge.v4;

// 将具体的礼物作为成员变量存在Gift中 public abstract class Gift { GiftImpl impl; }

  1. <a name="SROKV"></a>
  2. ### WarmGift类
  3. ```java
  4. package com.mashibing.dp.bridge.v4;
  5. public class WarmGift extends Gift {
  6. public WarmGift(GiftImpl impl) {
  7. this.impl = impl;
  8. }
  9. }

WildGift类

  1. package com.mashibing.dp.bridge.v4;
  2. public class WildGift extends Gift {
  3. public WildGift(GiftImpl impl) {
  4. this.impl = impl;
  5. }
  6. }

GiftImpl类

  1. package com.mashibing.dp.bridge.v4;
  2. public class GiftImpl {
  3. }

Book类(继承自GiftImpl)

  1. package com.mashibing.dp.bridge.v4;
  2. public class Book extends GiftImpl {
  3. }

Flower类

  1. package com.mashibing.dp.bridge.v4;
  2. public class Flower extends GiftImpl {
  3. }

MM类

  1. package com.mashibing.dp.bridge.v4;
  2. public class MM {
  3. String name;
  4. }

GG类

  1. package com.mashibing.dp.bridge.v4;
  2. public class GG {
  3. public void chase(MM mm) {
  4. // 将具体的礼物作为成员变量存在Gift中
  5. Gift g = new WarmGift(new Flower());
  6. give(mm, g);
  7. }
  8. public void give(MM mm, Gift g) {
  9. System.out.println(g + "gived!");
  10. }
  11. }

经典的桥接模式(GOF)

  • 字处理器在不同的操作系统上的实现
  • 小窗口、半大窗口、……

image.png
image.png
image.png