1.概述

  • 将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。 ——《设计模式》GoF
  • 核心: 单一职责原则 + 合成复用原则

    1.1动机

    1. - 由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个纬度的变化。
    2. - 如何应对这种“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?

    1.2结构

    1. - ![T][9{}9]$EV231OD~443L5S.png](https://cdn.nlark.com/yuque/0/2021/png/12524106/1628250993973-ff4409fc-ebf3-4494-a8e6-0f13c664049e.png#height=231&id=u20b2feaf&margin=%5Bobject%20Object%5D&name=T%5D%5B9%7B%7D9%5D%24EV231OD~443L5S.png&originHeight=461&originWidth=1133&originalType=binary&ratio=1&size=166258&status=done&style=none&width=567)
    2. - ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12524106/1625829456652-8f6d0110-8f07-47b9-891d-ce5dc64d1ec5.png#height=225&id=um7SS&margin=%5Bobject%20Object%5D&name=image.png&originHeight=300&originWidth=681&originalType=binary&ratio=1&size=158841&status=done&style=none&width=511)
  • Client类:桥接模式的调用者。
  • 抽象类(Abstraction):维护了Implementor及它的实现类ConcreteImplementorA。二者是聚合关系,Abstraction充当桥接类。
  • RefinedAbstraction:是Abstraction抽象类的子类。
  • Implementor:行为实现类的接口。
  • ConcreteImplementorA/B:行为的具体实现类。

    2.要点总结

    3.1总结

    1. 1. Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固 有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自纬度的变化,即“子类化”它们。
    2. 1. Bridge模式有时候类似于多继承方案,但是多继承方案往往违背 单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
    3. 1. Bridge模式的应用一般在“两个非常强的变化维度”,有时一个 类也有多于两个的变化维度,这时可以使用Bridge的扩展模式。

    2.2注意事项

    1. - 实现了抽象和实现部分的分离,从而极大的提供了系统的灵活性,让抽象部分和实现部分独立开来,这有助于系统进行分层设计,从而产生更好的结构化系统。
    2. - 对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了,其它的部分由具体业务来完成。
    3. - 桥接模式替代多层继承方案,可以减少子类的个数,降低系统的管理和维护成本。
    4. - 桥接模式的引入增加了系统的理解和设计难度,由于聚合关联关系建立在抽象层, 要求开发者针对抽象进行设计和编程
    5. - 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围有一定的局

限性,即需要有这样的应用场景。

3.案例

image.png

image.png

4.使用模式

方案

类图

  1. - ![7E703C29@BQ5AD{$HQ}@5UT.png](https://cdn.nlark.com/yuque/0/2021/png/12524106/1628253705327-44d68598-c7c3-4329-ad53-a6371ceb23fc.png#height=263&id=ua573678e&margin=%5Bobject%20Object%5D&name=7E703C29%40BQ5AD%7B%24HQ%7D%405UT.png&originHeight=525&originWidth=904&originalType=binary&ratio=1&size=138660&status=done&style=none&width=452)
  2. - ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12524106/1625755486664-435ce9b1-5212-43f0-98b1-664e39fa3bc7.png#height=804&id=u030e981d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=804&originWidth=1597&originalType=binary&ratio=1&size=79125&status=done&style=none&width=1597)

代码

  • //phone ```java public abstract class Phone {

    // 组合品牌 private Brand brand;

    Phone(Brand brand){

    1. this.brand = brand;

    }

    public void open(){

    1. brand.open();

    };

    public void call(){

    1. brand.call();

    }

    public void close(){

    1. brand.close();

    } }

class FoldedPhone extends Phone {

  1. public FoldedPhone(Brand brand) {
  2. super(brand);
  3. }
  4. @Override
  5. public void open() {
  6. super.open();
  7. System.out.println("折叠");
  8. }
  9. @Override
  10. public void call() {
  11. super.call();
  12. System.out.println("折叠");
  13. }
  14. @Override
  15. public void close() {
  16. super.close();
  17. System.out.println("折叠");
  18. }

}

class UpRightPhone extends Phone {

  1. public UpRightPhone(Brand brand) {
  2. super(brand);
  3. }
  4. @Override
  5. public void open() {
  6. super.open();
  7. System.out.println("滑盖");
  8. }
  9. @Override
  10. public void call() {
  11. super.call();
  12. System.out.println("滑盖");
  13. }
  14. @Override
  15. public void close() {
  16. super.close();
  17. System.out.println("滑盖");
  18. }

}

  1. - //Brand
  2. ```java
  3. public interface Brand {
  4. public void open();
  5. public void call();
  6. public void close();
  7. }
  8. class Vivo implements Brand {
  9. @Override
  10. public void open() {
  11. System.out.println("Vivo开机");
  12. }
  13. @Override
  14. public void call() {
  15. System.out.println("Vivo打电话");
  16. }
  17. @Override
  18. public void close() {
  19. System.out.println("Vivo关机");
  20. }
  21. }
  22. class XiaoMi implements Brand{
  23. @Override
  24. public void open() {
  25. System.out.println("小米开机");
  26. }
  27. @Override
  28. public void call() {
  29. System.out.println("小米打电话");
  30. }
  31. @Override
  32. public void close() {
  33. System.out.println("小米关机");
  34. }
  35. }
  • //Client 与 测试 ```java public class TestBrand { public static void main(String[] args) { Phone phone1 = new FoldedPhone(new XiaoMi());

    phone1.open(); phone1.call(); phone1.close();

    System.out.println(“===========”);

    UpRightPhone phone2 = new UpRightPhone(new Vivo()); phone2.open(); phone2.call(); phone2.close(); } }

class Client {

  1. private Phone phone;
  2. Client(Phone phone){
  3. this.phone = phone;
  4. }

}

```

5.经典使用


5.1JDBC中的桥接模式

  1. - ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12524106/1625831333532-20cb924a-9c40-4946-8eac-edd4bdfd83e0.png#height=724&id=u363e71da&margin=%5Bobject%20Object%5D&name=image.png&originHeight=724&originWidth=1099&originalType=binary&ratio=1&size=56938&status=done&style=none&width=1099)

x.其它

桥接模式其它应用场景

  1. - 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用.
  2. - 常见的应用场景:

-JDBC驱动程序
-银行转账系统
转账分类: 网上转账,柜台转账,AMT转账
转账用户类型:普通用户,银卡用户,金卡用户..
-消息管理
消息类型:即时消息,延时消息
消息分类:手机短信,邮件消息,QQ消息…

笔记

RKG8JYE2QNQARJ]8RQNHOB8.jpg