定义:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
在实际场景中,一个对象往往会有多个纬度的属性,而这个多个维度属性组合起来才能决定这个对象。 说人话就是比如: 一个图形可以分为形状和颜色两方面来描述, 由此得出的可以有红色长方形、黑色长方形、红色圆形等等。 假如有N种形状, M种颜色, 那么会得到 MN 个图形。 放在程序中来说就会有 MN 个类, 当M和N都比较大的时候, 就会出现很多的类, 这就称作为 类爆炸。桥接模式就是用来解决类爆炸的问题的
类图如下:
3-1Q115125253H1.gif

1、场景描述

现有红色矩形、黄色矩形、红色圆形、黄色圆形。采用桥接模式实现。

2、实现

  1. /// <summary>
  2. /// 颜色抽象
  3. /// </summary>
  4. public interface IColor
  5. {
  6. /// <summary>
  7. /// 获取颜色
  8. /// </summary>
  9. string GetColor();
  10. }
  11. /// <summary>
  12. /// 具体实现-红色
  13. /// </summary>
  14. public class RedColor : IColor
  15. {
  16. public string GetColor()
  17. {
  18. return "红色";
  19. }
  20. }
  21. /// <summary>
  22. /// 具体实现-黄色
  23. /// </summary>
  24. public class YellowColor : IColor
  25. {
  26. public string GetColor()
  27. {
  28. return "黄色";
  29. }
  30. }
  31. /// <summary>
  32. /// 抽象-形状
  33. /// </summary>
  34. public abstract class AbstractShape
  35. {
  36. protected readonly IColor color;
  37. public AbstractShape(IColor color)
  38. {
  39. this.color = color;
  40. }
  41. /// <summary>
  42. /// 显示具体形状
  43. /// </summary>
  44. public abstract void ShowSpecificShape();
  45. }
  46. /// <summary>
  47. /// 矩形
  48. /// </summary>
  49. public class Rectangle : AbstractShape
  50. {
  51. public Rectangle(IColor color) : base(color)
  52. {
  53. }
  54. public override void ShowSpecificShape()
  55. {
  56. Console.WriteLine($"{color.GetColor()}矩形");
  57. }
  58. }
  59. /// <summary>
  60. /// 圆形
  61. /// </summary>
  62. public class Circle : AbstractShape
  63. {
  64. public Circle(IColor color) : base(color)
  65. {
  66. }
  67. public override void ShowSpecificShape()
  68. {
  69. Console.WriteLine($"{color.GetColor()}圆形");
  70. }
  71. }

以上代码类之间关系如下:
企业微信截图_20210927162918.png

3、优缺点

通过以上代码可以知道,当我们需要增加一个绿色矩形的时候, 只需要添加一个对应的绿色颜色类就行了。然后客户端使用将这个颜色传入即可。 这符合开闭原则,扩展很方便。最重要的是通过抽象,然后再通过聚合颜色的方式,大大的减少了本来类的数量,避免了类爆炸。但是桥接模式的实现需要一定的抽象能力,需要正确的识别出独立变化的纬度,这也间接了增加了理解和设计难度。

4、应用场景

凡是存在两个纬度, 而且多对多的都可以考虑桥接模式。 比如: Repository 和 DB 之间的多对多。

  • Repository1 —> MySQL、Oracle、SqlServer
  • Repository2 —> MySQL、Oracle、SqlServer
  • …..