适配器模式

将类的接口转换为客户期望的另一个接口。适配器(或包装器)允许类一起工作,否则由于不兼容的接口。适配器模式的动机是,如果我们可以修改接口,我们可以重用现有的软件。

  1. 适配器模式依赖于对象组合。

  2. 客户端调用 Adapter 对象上的操作。

  3. 适配器调用 Adaptee 来执行操作。

  4. 在 STL 中,堆栈适用于向量:当堆栈执行 push() 时,底层向量执行 vector :: push_back()

例:

#include <iostream>

// Desired interface (Target)
class Rectangle 
{
  public:
    virtual void draw() = 0;
};

// Legacy component (Adaptee)
class LegacyRectangle 
{
  public:
    LegacyRectangle(int x1, int y1, int x2, int y2) {
        x1_ = x1;
        y1_ = y1;
        x2_ = x2;
        y2_ = y2;
        std::cout << "LegacyRectangle(x1,y1,x2,y2)\n";
    }
    void oldDraw() {
        std::cout << "LegacyRectangle:  oldDraw(). \n";
    }
  private:
    int x1_;
    int y1_;
    int x2_;
    int y2_;
};

// Adapter wrapper
class RectangleAdapter: public Rectangle, private LegacyRectangle 
{
  public:
    RectangleAdapter(int x, int y, int w, int h):
      LegacyRectangle(x, y, x + w, y + h) {
         std::cout << "RectangleAdapter(x,y,x+w,x+h)\n";
      }

    void draw() {
        std::cout << "RectangleAdapter: draw().\n"; 
        oldDraw();
    }
};

int main()
{
  int x = 20, y = 50, w = 300, h = 200;
  Rectangle *r = new RectangleAdapter(x,y,w,h);
  r->draw();
}

//Output:
//LegacyRectangle(x1,y1,x2,y2)
//RectangleAdapter(x,y,x+w,x+h)

代码摘要:

  1. 客户认为他正在和一个人交谈

  2. 目标是 Rectangle 类。这是客户端调用方法的内容。

     Rectangle *r = new RectangleAdapter(x,y,w,h);
     r->draw();
    
  3. 请注意,适配器类使用多重继承。

     class RectangleAdapter: public Rectangle, private LegacyRectangle {
         ...
     }
    
  4. 适配器 RectangleAdapter 允许 LegacyRectangle 通过继承 BOTH 类来响应请求(draw()Rectangle 上)。

  5. LegacyRectangle 类没有与 Rectangle 相同的方法(draw()),但是 Adapter(RectangleAdapter) 可以接受 Rectangle 方法调用并转向并调用 LegacyRectangleoldDraw() 上的方法。

     class RectangleAdapter: public Rectangle, private LegacyRectangle {
       public:
         RectangleAdapter(int x, int y, int w, int h):
           LegacyRectangle(x, y, x + w, y + h) {
             std::cout << "RectangleAdapter(x,y,x+w,x+h)\n";
           }
    
         void draw() {
             std::cout << "RectangleAdapter: draw().\n"; 
             oldDraw();
         }
     };
    

适配器设计模式将一个类的接口转换为兼容但不同的接口。因此,这与代理模式类似,因为它是单组件包装器。但是适配器类和原始类的接口可能不同。

正如我们在上面的示例中看到的,此适配器模式对于为现有 API 公开不同的接口以允许其与其他代码一起使用非常有用。此外,通过使用适配器模式,我们可以采用异构接口,并对它们进行转换以提供一致的 API。

Bridge 模式具有类似于对象适配器的结构,但 Bridge 具有不同的意图:它旨在接口与其实现分离,以便可以轻松且独立地改变它们。一个适配器是为了改变界面的的现有对象。