(6)适配器模式

适配器模式的核心思想,将一个类的接口转换成客户期望的另一个接口,让原本不兼容的类可以一起工作。
 - 解决 “已有类,但接口不匹配” 的问题
 - 继承多个接口实现
 - 常用于集成老系统、第三方库、跨平台开发
// ============ 目标接口(客户端期望的接口) ============
class USBCharger {
public:
    virtual ~USBCharger() = default;
    virtual void chargeWith5V() = 0;
};
// ============ 已有类(被适配者) ============
class WallSocket {
public:
    void supply220V() {
        std::cout << "墙壁插座提供 220V 交流电\n";
    }
};
// ============ 适配器方案1-继承多个(角色) ============
class ChargerAdapter : public USBCharger, private WallSocket {
public:
    // 实现目标接口,内部调用被适配者的功能
    void chargeWith5V() override {
        std::cout << "【适配器工作】:开始转换电压...\n";
        supply220V();
        std::cout << "【适配器工作】:220V → 5V 转换完成,开始充电\n";
    }
};
// ============ 适配器方案2-持有被适配者 ============
class ObjectAdapter : public USBCharger {
private:
    WallSocket& socket_;  // 持有被适配者引用
public:
    explicit ObjectAdapter(WallSocket& socket) : socket_(socket) {}

    void chargeWith5V() override {
        std::cout << "【适配器工作】:开始转换电压...\n";
        socket_.supply220V();
        std::cout << "【适配器工作】:220V → 5V 转换完成,开始充电\n";
    }
};
--------------------------------------------------------
// 使用
WallSocket socket;
ObjectAdapter adapter(socket);
startCharging(&adapter);
进阶-使用模板优化
 - 用模板实现通用适配器
 - 支持任意“被适配者”和“目标接口”
 - 编译时绑定,无运行时开销
 - 实现“函数接口适配”或“类型接口适配”
// ============ 被适配者 1 ============
class WallSocket {
public:
    void supply220V() {
        std::cout << "墙壁插座提供 220V 交流电\n";
    }
};
// ============ 被适配者 2 ============
class PowerBank {
public:
    void output220V() {
        std::cout << "移动电源模拟输出 220V\n";
    }
};
// ============ 通用适配器模板(基于函数对象) ============
template <typename SupplyFunc>
class VoltageAdapter {
private:
    SupplyFunc supplyFunc_;  // 存储“如何供电”的可调用对象(函数、lambda、bind)

public:
    // 构造函数:接受任意可调用对象
    explicit VoltageAdapter(SupplyFunc func) : supplyFunc_(std::move(func)) {}

    // 提供标准接口
    void chargeWith5V() {
        std::cout << "【适配器工作】:开始转换电压...\n";
        supplyFunc_();  // 调用传入的供电逻辑
        std::cout << "【适配器工作】:220V → 5V 转换完成,开始充电\n";
    }
};

// 为了支持拷贝或移动,可添加以下(现代编译器通常自动生成)
VoltageAdapter(const VoltageAdapter&) = default;
VoltageAdapter& operator=(const VoltageAdapter&) = default;
VoltageAdapter(VoltageAdapter&&) = default;
VoltageAdapter& operator=(VoltageAdapter&&) = default;
// 普通函数,接受任何有 chargeWith5V() 方法的对象
template <typename Charger>
void startCharging(Charger& charger) {
    std::cout << "开始充电...\n";
    charger.chargeWith5V();
    std::cout << "充电完成。\n\n";
}
int main() {

    WallSocket socket; // 为 WallSocket 创建适配器
    VoltageAdapter adapter1([&socket]() {
        socket.supply220V();
    });
    startCharging(adapter1);

    PowerBank bank;// 为 PowerBank 创建适配器
    VoltageAdapter adapter2([&bank]() {
        bank.output220V();
    });
    startCharging(adapter2);

    return 0;
}
posted @ 2018-12-12 21:49  osbreak  阅读(164)  评论(0)    收藏  举报