C++如何实现一个适配器(Adapter)设计模式?(代码示例)

适配器模式通过转换接口使不兼容类协同工作,C++中推荐对象适配器;目标接口IDrawer定义drawCircle,Adaptee LegacyShapeRenderer提供renderCircleAt。

适配器模式用于让两个接口不兼容的类能够协同工作,核心是“转换接口”。C++ 中常用类适配器(继承)或对象适配器(组合)实现,推荐对象适配器——更灵活、符合合成复用原则。

定义目标接口(Target)

这是客户端期望使用的统一接口。例如,一个绘图系统只认 IDrawer

class IDrawer {
public:
    virtual ~IDrawer() = default;
    virtual void drawCircle(double x, double y, double r) = 0;
};

已有不兼容的类(Adaptee)

假设第三方库提供了一个 LegacyShapeRenderer,接口完全不同:

class LegacyShapeRenderer {
public:
    void renderCircleAt(double centerX, double centerY, double radiusInPixels) {
        std::cout << "Legacy: drawing circle at (" 
                  << centerX << ", " << centerY 
                  << ") with radius " << radiusInPixels << "\n";
    }
};

实现适配器(Object Adapter)

通过组合持有 LegacyShapeRenderer 实例,并在 drawCircle 中转调其方法。注意单位/参数语义的转换(如这里假设像素单位无需换算):

class DrawerAdapter : public IDrawer {
private:
    LegacyShapeRenderer legacyRenderer;

public: void drawCircle(double x, double y, double r) override { // 转换调用:参数名、顺序、含义都做了适配 legacyRenderer.renderCircleAt(x, y, r); } };

客户端使用

客户端只依赖 IDrawer,完全 unaware 底层是新实现还是旧库封装:

int main() {
    DrawerAdapter adapter;
    IDrawer* drawer = &adapter;
drawer->drawCircle(10.5, 20.0, 5.0);  // 输出 Legacy 日志
return 0;

}

若需运行时切换被适配对象(比如支持多个 legacy 类),可将 LegacyShapeRenderer 改为指针或智能指针,并在构造函数注入;类适配器(继承 LegacyShapeRenderer)也可行,但 C++ 不支持多继承时受限,且紧耦合 legacy 类的实现细节。