桥接模式(Bridge Pattern)定义如下:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

桥接模式组成如下:

组成
Abstraction(抽象化) 定义抽象类,并包含一个对实现化对象的引用
Refined Abstraction(扩展抽象化) 是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法
Implementor(实现化) 定义实现化角色的接口,供扩展抽象化角色调用
Concrete Implementor(具体实现化) 给出实现化角色接口的具体实现

桥接模式结构图如下:

设计模式—桥接模式 - 图1

桥接模式的优点

  1. 抽象与实现分离,扩展能力强
  2. 符合开闭原则
  3. 符合合成复用原则
  4. 其实现细节对客户透明

桥接模式的缺点

由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,能正确地识别出系统中两个独立变化的维度,这增加了系统的理解与设计难度。

桥接模式的应用场景

  1. 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时
  2. 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时
  3. 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时

桥接模式使用示例

假设某个汽车厂商生产三种品牌的汽车:Big、Tiny和Boss,每种品牌又可以选择燃油、纯电和混合动力。如果用传统的继承来表示各个最终车型,一共有3个抽象类加9个最终子类:
image.png
如果要新增一个品牌,或者加一个新的引擎(比如核动力),那么子类的数量增长更快。

为了避免这种直接继承带来的子类爆炸,可以使用桥接模式。在桥接模式中,首先把Car按品牌进行子类化,但是,每个品牌选择什么发动机,不再使用子类扩充,而是通过一个抽象的“修正”类,以组合的形式引入

  1. public class BridgePattern {
  2. public static abstract class Car {
  3. // 引用Engine:
  4. protected Engine engine;
  5. public Car(Engine engine) {
  6. this.engine = engine;
  7. }
  8. public abstract void drive();
  9. }
  10. public interface Engine {
  11. void start();
  12. }
  13. // 修正的抽象类RefinedCar中定义一些额外操作
  14. public static abstract class RefinedCar extends Car {
  15. public RefinedCar(Engine engine) {
  16. super(engine);
  17. }
  18. @Override
  19. public void drive() {
  20. this.engine.start();
  21. System.out.println("Drive " + getBrand() + " car...");
  22. }
  23. public abstract String getBrand();
  24. }
  25. public static class BossCar extends RefinedCar {
  26. public BossCar(Engine engine) {
  27. super(engine);
  28. }
  29. @Override
  30. public String getBrand() {
  31. return "Boss";
  32. }
  33. }
  34. public static class BigCar extends RefinedCar {
  35. public BigCar(Engine engine) {
  36. super(engine);
  37. }
  38. @Override
  39. public String getBrand() {
  40. return "big";
  41. }
  42. }
  43. public static class TinyCar extends RefinedCar {
  44. public TinyCar(Engine engine) {
  45. super(engine);
  46. }
  47. @Override
  48. public String getBrand() {
  49. return "tiny";
  50. }
  51. }
  52. public static class HybridEngine implements Engine {
  53. public void start() {
  54. System.out.println("Start Hybrid Engine...");
  55. }
  56. }
  57. public static class FuelEngine implements Engine {
  58. public void start() {
  59. System.out.println("Start Fuel Engine...");
  60. }
  61. }
  62. public static class ElectricEngine implements Engine {
  63. public void start() {
  64. System.out.println("Start Electric Engine...");
  65. }
  66. }
  67. public static void main(String[] args) {
  68. RefinedCar car = new BossCar(new HybridEngine());
  69. car.drive();
  70. car = new BigCar(new FuelEngine());
  71. car.drive();
  72. car = new TinyCar(new ElectricEngine());
  73. car.drive();
  74. }
  75. }

程序运行结果如下:

:::success Start Hybrid Engine…
Drive Boss car… ::: :::success Start Fuel Engine… ::: :::success Drive big car… ::: :::success Start Electric Engine… ::: :::success Drive tiny car… :::