適配器模式(Adapter Pattern)是一種結構型設計模式,它允許不兼容的接口之間能夠協同工作。
概念解析
適配器模式的核心思想是:
-
接口轉換:將一個類的接口轉換成客戶希望的另一個接口
-
兼容性:使原本由于接口不兼容而不能一起工作的類可以一起工作
-
包裝:通過包裝的方式實現接口轉換
主要組成部分
-
目標接口(Target):客戶端期望的接口
-
適配者(Adaptee):需要被適配的現有接口
-
適配器(Adapter):將適配者接口轉換為目標接口的類
代碼示例
下面是一個完整的適配器模式示例,包含詳細注釋:
#include <iostream>
#include <memory>
#include <string>
#include <cmath>// ==================== 目標接口 ====================
// 客戶端期望的幾何圖形接口
class Shape {
public:virtual void draw(int x1, int y1, int x2, int y2) = 0;virtual ~Shape() = default;
};// ==================== 適配者 ====================
// 現有的直線繪制類(不兼容的接口)
class LegacyLine {
public:void draw(int x1, int y1, int x2, int y2) {std::cout << "繪制直線: 從(" << x1 << "," << y1 << ")到(" << x2 << "," << y2 << ")" << std::endl;}
};// 現有的矩形繪制類(不兼容的接口)
class LegacyRectangle {
public:void draw(int x, int y, int w, int h) {std::cout << "繪制矩形: 左上角(" << x << "," << y << "), 寬" << w << ", 高" << h << std::endl;}
};// ==================== 適配器 ====================
// 直線適配器(對象適配器)
class LineAdapter : public Shape {
private:std::unique_ptr<LegacyLine> adaptee_;public:LineAdapter() : adaptee_(std::make_unique<LegacyLine>()) {}void draw(int x1, int y1, int x2, int y2) override {adaptee_->draw(x1, y1, x2, y2);}
};// 矩形適配器(對象適配器)
class RectangleAdapter : public Shape {
private:std::unique_ptr<LegacyRectangle> adaptee_;public:RectangleAdapter() : adaptee_(std::make_unique<LegacyRectangle>()) {}void draw(int x1, int y1, int x2, int y2) override {int x = std::min(x1, x2);int y = std::min(y1, y2);int width = std::abs(x2 - x1);int height = std::abs(y2 - y1);adaptee_->draw(x, y, width, height);}
};// ==================== 類適配器(通過多重繼承)====================
class ClassAdapter : public Shape, private LegacyRectangle {
public:void draw(int x1, int y1, int x2, int y2) override {int x = std::min(x1, x2);int y = std::min(y1, y2);int width = std::abs(x2 - x1);int height = std::abs(y2 - y1);LegacyRectangle::draw(x, y, width, height);}
};// ==================== 客戶端代碼 ====================
void drawShape(Shape& shape, int x1, int y1, int x2, int y2) {shape.draw(x1, y1, x2, y2);
}int main() {std::cout << "=== 適配器模式演示 ===" << std::endl;// 使用對象適配器std::cout << "\n使用對象適配器:" << std::endl;LineAdapter lineAdapter;drawShape(lineAdapter, 10, 20, 30, 40);RectangleAdapter rectAdapter;drawShape(rectAdapter, 10, 20, 30, 40);// 使用類適配器std::cout << "\n使用類適配器:" << std::endl;ClassAdapter classAdapter;drawShape(classAdapter, 15, 25, 35, 45);// 直接使用Legacy類(不兼容)std::cout << "\n直接使用Legacy類:" << std::endl;LegacyLine line;line.draw(5, 5, 25, 25);LegacyRectangle rect;rect.draw(5, 5, 20, 20); // 參數含義不同return 0;
}
模式優勢
-
兼容性:使不兼容的接口能夠協同工作
-
復用性:可以復用現有的類,無需修改其源代碼
-
靈活性:可以同時適配多個適配者類
-
開閉原則:引入適配器而不改變現有代碼
-
透明性:對客戶端隱藏了適配的細節
適用場景
-
當需要使用現有的類,但其接口與你的需求不匹配時
-
當想要創建一個可復用的類,該類與不相關或不可預見的類協同工作
-
當需要統一多個現有子類的接口時(適配器可以統一這些接口)
-
在遺留代碼集成、第三方庫適配等場景中