Adapter - shoonie/StudyingDesignPattern GitHub Wiki

Intent

Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interface.

Diagram

A class adapter

disgram

An object adapter

disgram

Consequences

A class adapter

  • adapts Adaptee to Target by committing to concrete Adaptee class.
  • lets Adapter override some of Adaptee's behavior, since Adapter is a subclass of Adaptee.
  • introduces only one object, and no additional pointer indirection is needed to get to the adaptee.

An object adapter

  • lets single Adapter work with many Adaptees
  • makes it harder to override Adaptee behavior.

Implementation

  1. Implementing class adapters in C++
  2. Pluggable adapters.

Sample Code

A class adapter - use multiple inheritance

//get from https://sourcemaking.com/design_patterns/adapter/cpp/1
#include <iostream.h>

typedef int Coordinate;
typedef int Dimension;

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

// Legacy component
class LegacyRectangle
{
  public:
    LegacyRectangle(Coordinate x1, Coordinate y1, Coordinate x2, Coordinate y2)
    {
        x1_ = x1;
        y1_ = y1;
        x2_ = x2;
        y2_ = y2;
        cout << "LegacyRectangle:  create.  (" << x1_ << "," << y1_ << ") => ("
          << x2_ << "," << y2_ << ")" << endl;
    }
    void oldDraw()
    {
        cout << "LegacyRectangle:  oldDraw.  (" << x1_ << "," << y1_ << 
          ") => (" << x2_ << "," << y2_ << ")" << endl;
    }
  private:
    Coordinate x1_;
    Coordinate y1_;
    Coordinate x2_;
    Coordinate y2_;
};

// Adapter wrapper
class RectangleAdapter: public Rectangle, private LegacyRectangle
{
  public:
    RectangleAdapter(Coordinate x, Coordinate y, Dimension w, Dimension h):
      LegacyRectangle(x, y, x + w, y + h)
    {
        cout << "RectangleAdapter: create.  (" << x << "," << y << 
          "), width = " << w << ", height = " << h << endl;
    }
    virtual void draw()
    {
        cout << "RectangleAdapter: draw." << endl;
        oldDraw();
    }
};

int main()
{
  Rectangle *r = new RectangleAdapter(120, 200, 60, 40);
  r->draw();
}

An object adapter - use object composition

// get from https://www.codeproject.com/Tips/595716/Adapter-Design-Pattern-in-Cplusplus
// Abstract Target
class AbstractPlug {
public:
  void virtual RoundPin(){}
  void virtual PinCount(){}
};
// Concrete Target
class Plug : public AbstractPlug {
public:
  void RoundPin() {
    cout << " I am Round Pin" << endl;
  }
  void PinCount() {
    cout << " I have two pins" << endl;
  }
};
// Abstract Adaptee
class AbstractSwitchBoard {
public:
  void virtual FlatPin() {}
  void virtual PinCount() {}
};
// Concrete Adaptee
class SwitchBoard : public AbstractSwitchBoard {
public:
  void FlatPin() {
        cout << " Flat Pin" << endl;
  }
  void PinCount() {
        cout << " I have three pins" << endl;
  }
};
// Adapter
class Adapter : public AbstractPlug {
public:
  AbstractSwitchBoard *T;
  Adapter(AbstractSwitchBoard *TT) {
        T = TT;
  }
  void RoundPin() {
        T->FlatPin();
  }
  void PinCount() {
        T->PinCount();
  }
};
// Client code
void _tmain(int argc, _TCHAR* argv[])
{
  SwitchBoard *mySwitchBoard = new SwitchBoard; // Adaptee
  // Target = Adapter(Adaptee)
  AbstractPlug *adapter = new Adapter(mySwitchBoard);
  adapter->RoundPin();
  adapter->PinCount();
}
⚠️ **GitHub.com Fallback** ⚠️