当前位置:   article > 正文

设计模式-11 - Bridge Method 桥接模式

设计模式-11 - Bridge Method 桥接模式
设计模式-11 - Bridge Method 桥接模式

1.定义

桥接模式是一种设计模式,它将抽象部分与其实现部分分离,使它们可以独立变化。它允许你改变抽象部分和实现部分的实现,而无需更改它们的接口。
结构:

桥接模式涉及四个主要角色:

  • 抽象(Abstraction):定义抽象接口,客户端代码与之交互。
  • 实现(Implementor):实现抽象接口并提供具体行为。
  • 扩展抽象(Refined Abstraction):扩展抽象接口,提供更加具体的接口。
  • 具体实现(Concrete Implementor):实现扩展抽象接口并提供具体的实现。

一个常见的桥接模式示例是图形绘制库。抽象接口可以定义绘制不同形状的方法,而实现对象可以提供不同平台(例如 Windows 或 macOS)的具体绘制实现。这允许开发人员使用相同的抽象接口在不同平台上绘制形状,而无需更改代码。


2.内涵

桥接模式工作原理

  • 客户端代码通过抽象接口与桥接模式交互。
  • 抽象接口将请求委托给实现对象。
  • 实现对象执行请求并返回结果。
  • 桥接模式允许在不改变抽象接口的情况下改变实现。
  • 还可以扩展抽象接口和具体实现,以提供新的功能或行为。

桥接模式核心组件及调用关系 ASCII 图

  1.            +----------------+
  2.            | Abstraction    |
  3.            +----------------+
  4.                   |
  5.                   v
  6.      +-----------------------+------------------+
  7.      | RefinedAbstraction1 | RefinedAbstraction2 |
  8.      +--------------+-----------------------------+
  9.                   |                  |
  10.                   v                  v
  11.            +--------------+           +--------------+
  12.            | ConcreteImplementor1 | | ConcreteImplementor2 |
  13.            +--------------+           +--------------+
  14.            


调用关系:

客户端代码通过 RefinedAbstraction 类与 Abstraction 类进行交互。
RefinedAbstraction 类将调用委托给其关联的 ConcreteImplementor 类。
组件说明:

Abstraction:定义抽象接口,它定义了客户端代码与桥接模式交互的方式。
RefinedAbstraction:扩展 Abstraction 接口,为特定的实现提供不同的行为。
ConcreteImplementor:实现 Abstraction 接口,提供具体的实现细节。

           
3.使用示例
  1. #include <iostream>
  2. // Abstraction: Shape
  3. class Shape {
  4. public:
  5.     virtual void draw() = 0;
  6. };
  7. // Implementations: Renderer (VectorRenderer and
  8. // RasterRenderer)
  9. class Renderer {
  10. public:
  11.     virtual void render() = 0;
  12. };
  13. class VectorRenderer : public Renderer {
  14. public:
  15.     void render() override
  16.     {
  17.         std::cout << "Rendering as a vector\n";
  18.     }
  19. };
  20. class RasterRenderer : public Renderer {
  21. public:
  22.     void render() override
  23.     {
  24.         std::cout << "Rendering as a raster\n";
  25.     }
  26. };
  27. // Concrete Abstractions: Circle and Square
  28. class Circle : public Shape {
  29. public:
  30.     Circle(Renderer& renderer)
  31.         : renderer(renderer)
  32.     {
  33.     }
  34.     void draw() override
  35.     {
  36.         std::cout << "Drawing a circle ";
  37.         renderer.render();
  38.     }
  39. private:
  40.     Renderer& renderer;
  41. };
  42. class Square : public Shape {
  43. public:
  44.     Square(Renderer& renderer)
  45.         : renderer(renderer)
  46.     {
  47.     }
  48.     void draw() override
  49.     {
  50.         std::cout << "Drawing a square ";
  51.         renderer.render();
  52.     }
  53. private:
  54.     Renderer& renderer;
  55. };
  56. int main()
  57. {
  58.     VectorRenderer vectorRenderer;
  59.     RasterRenderer rasterRenderer;
  60.     Circle circle(vectorRenderer);
  61.     Square square(rasterRenderer);
  62.     circle.draw(); // Output: Drawing a circle Rendering as
  63.                 // a vector
  64.     square.draw(); // Output: Drawing a square Rendering as
  65.                 // a raster
  66.     return 0;
  67. }

4.注意事项

桥接模式注意事项:

  • 复杂性:桥接模式引入了额外的抽象层,这可能会增加代码的复杂性。
  • 性能开销:在桥接模式中,抽象类和具体实现类之间的调用可能引入性能开销。
  • 过度设计:在某些情况下,桥接模式可能被过度使用,导致不必要的复杂性。
  • 多重继承的替代方案:在某些语言中,多重继承可以提供与桥接模式类似的功能,但可能更简单且性能更高。
  • 接口的稳定性:桥接模式依赖于稳定的抽象接口。如果接口经常更改,则可能会导致应用程序不稳定。


何时使用桥接模式:

  • 当你需要在不改变抽象部分的情况下改变实现部分时。
  • 当你想要将不同类型的实现封装在统一的接口后面时。
  • 当你想在多个平台或环境中使用相同的抽象接口时。


何时不使用桥接模式:

  • 当抽象部分和实现部分之间没有明确的分离时。
  • 当性能开销不可接受时。
  • 当代码的复杂性已经很高时。

5.最佳实践

桥接模式最佳实践:

  • 明确分离抽象和实现:确保抽象接口只定义高级概念,而具体实现提供具体的实现细节。
  • 保持抽象接口稳定:避免经常更改抽象接口,因为这可能会破坏依赖于该接口的代码。
  • 使用组合而非继承:桥接模式通常使用组合而不是继承来实现分离,这提供了更大的灵活性。
  • 避免过度使用:只有在确实需要在不更改抽象的情况下更改实现时才使用桥接模式。
  • 考虑性能开销:在桥接模式中,抽象类和具体实现类之间的调用可能会引入性能开销,因此在性能关键的应用程序中要谨慎使用。
  • 使用清晰的命名约定:为抽象接口、扩展抽象和具体实现类使用明确的命名约定,以提高代码的可读性和可维护性。
6.总结


桥接模式通过将抽象部分和实现部分分离,使得两者可以独立变化,能够做到抽象接口只定义高级概念,而具体实现提供具体的实现细节

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/568958
推荐阅读
相关标签
  

闽ICP备14008679号