Adapter Pattern 將不相容介面轉換為客戶期望介面。現實類比:筆電內部用 DC 電,插座提供 AC 電,需 AC-DC 轉接器;USB 轉 COM 連接線讓無 COM 埠筆電連接開發板。
Grapher 使用 IDrawStrategy.draw(),既有框架提供 IPaint.paint() 及 Triangle/Circle/Square。無法修改框架碼,故撰寫適配器轉換介面。
class TriangleDrawAdapter : public IDrawStrategy, private Triangle {
public:
virtual void draw() const { paint(); }
};
對 IDrawStrategy 公有繼承(是一種關係),對 Triangle 私有繼承(僅為實作細節,非介面契約)。
#include <iostream>
using namespace std;
class IDrawStrategy { public: virtual void draw() const = 0; };
class Grapher {
IDrawStrategy* _drawStrategy;
public:
Grapher(IDrawStrategy* ds = 0) : _drawStrategy(ds) {}
void drawShape() const { if (_drawStrategy) _drawStrategy->draw(); }
void setShape(IDrawStrategy* ds) { _drawStrategy = ds; }
};
class IPaint { public: virtual void paint() const = 0; };
class Triangle : public IPaint { public: void paint() const { cout << "Draw Triangle" << endl; } };
class Circle : public IPaint { public: void paint() const { cout << "Draw Circle" << endl; } };
class Square : public IPaint { public: void paint() const { cout << "Draw Square" << endl; } };
class TriangleDrawAdapter : public IDrawStrategy, private Triangle { public: virtual void draw() const { paint(); } };
class CircleDrawAdapter : public IDrawStrategy, private Circle { public: virtual void draw() const { paint(); } };
class SquareDrawAdapter : public IDrawStrategy, private Square { public: virtual void draw() const { paint(); } };
int main() {
Grapher grapher(new TriangleDrawAdapter());
grapher.drawShape();
grapher.setShape(new CircleDrawAdapter());
grapher.drawShape();
grapher.setShape(new SquareDrawAdapter());
grapher.drawShape();
}
此為經典類別適配器實作,後續將展示物件適配器與泛型改良版本。