第六章:适配器模式 - 接口转换的艺术大师

第六章:适配器模式 - 接口转换的艺术大师

故事延续:转接高手的兼容之道

在Prototype展示完他的克隆大法后,Adapter忙碌地走出,他身上挂着的各种转接头叮当作响。这位看起来最是忙碌的大师,一边走一边还在摆弄手中的工具。

"Prototype兄的克隆确实高效,"Adapter笑着说道,"但在软件江湖中,我们常常需要让不兼容的接口能够协同工作。我的武学核心在于------将一个类的接口转换成客户期望的另一个接口。让原本由于接口不兼容而不能一起工作的类可以一起工作!"

适配器模式的武学精要

核心心法

Adapter展示着他身上的各种转接头:"我的十二字真言是------兼容并包,转接万物。通过创建一个中间适配器类,我可以让两个不兼容的接口能够无缝协作,就像给不同规格的插头配上合适的转换器。"

C++ 代码实战
cpp 复制代码
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <cmath>

// 目标接口:现代支付系统期望的接口
class ModernPayment {
public:
    virtual ~ModernPayment() = default;
    virtual bool processPayment(double amount, const std::string& currency) = 0;
    virtual std::string getPaymentMethod() const = 0;
    virtual void refundPayment(const std::string& transactionId) = 0;
};

// 被适配者:传统的银行支付系统(不兼容的接口)
class LegacyBankSystem {
private:
    std::string bankCode_;
    std::string accountNumber_;
    
public:
    LegacyBankSystem(const std::string& bankCode, const std::string& accountNumber)
        : bankCode_(bankCode), accountNumber_(accountNumber) {}
    
    // 传统支付方法 - 参数与现代系统不兼容
    bool makeBankPayment(int cents, const std::string& bankCode, const std::string& account) {
        std::cout << "🏦 传统银行支付: " << cents << " 分到银行 " << bankCode 
                  << " 账户 " << account << std::endl;
        return true;
    }
    
    // 传统退款方法
    void processBankRefund(int cents, const std::string& transactionCode) {
        std::cout << "🏦 传统银行退款: " << cents << " 分,交易码 " << transactionCode << std::endl;
    }
    
    // 获取银行信息
    std::string getBankInfo() const {
        return "银行代码: " + bankCode_ + ", 账户: " + accountNumber_;
    }
    
    // 验证账户
    bool validateAccount() const {
        std::cout << "✅ 验证传统银行账户: " << accountNumber_ << std::endl;
        return !accountNumber_.empty();
    }
};

// 被适配者:第三方支付系统(另一个不兼容的接口)
class ThirdPartyPayment {
private:
    std::string apiKey_;
    std::string merchantId_;
    
public:
    ThirdPartyPayment(const std::string& apiKey, const std::string& merchantId)
        : apiKey_(apiKey), merchantId_(merchantId) {}
    
    // 第三方支付方法 - 参数格式完全不同
    bool sendPaymentRequest(double dollarAmount, const std::string& merchant, const std::string& apiKey) {
        std::cout << "🔗 第三方支付: $" << dollarAmount << " 到商户 " << merchant 
                  << " API密钥: " << apiKey.substr(0, 8) << "..." << std::endl;
        return true;
    }
    
    // 第三方退款
    bool initiateRefund(double dollarAmount, const std::string& paymentId) {
        std::cout << "🔗 第三方退款: $" << dollarAmount << " 支付ID: " << paymentId << std::endl;
        return true;
    }
    
    // 获取商户信息
    std::string getMerchantInfo() const {
        return "商户ID: " + merchantId_ + ", API密钥: " + apiKey_.substr(0, 8) + "...";
    }
};

// 类适配器:通过多重继承适配传统银行系统
class BankPaymentAdapter : public ModernPayment, private LegacyBankSystem {
public:
    BankPaymentAdapter(const std::string& bankCode, const std::string& accountNumber)
        : LegacyBankSystem(bankCode, accountNumber) {}
    
    bool processPayment(double amount, const std::string& currency) override {
        std::cout << "🔄 银行适配器: 转换支付请求..." << std::endl;
        
        // 转换金额:美元转分
        int cents = static_cast<int>(amount * 100);
        
        // 转换货币(简化处理)
        if (currency != "USD") {
            std::cout << "💱 货币转换: " << currency << " -> USD" << std::endl;
        }
        
        // 调用传统银行方法
        return makeBankPayment(cents, getBankCode(), getAccountNumber());
    }
    
    std::string getPaymentMethod() const override {
        return "传统银行支付 (" + getBankInfo() + ")";
    }
    
    void refundPayment(const std::string& transactionId) override {
        std::cout << "🔄 银行适配器: 转换退款请求..." << std::endl;
        // 在实际系统中,这里会有金额查询逻辑
        processBankRefund(10000, transactionId); // 假设退款100美元
    }
    
private:
    std::string getBankCode() const {
        return "BANK001"; // 从配置或数据库中获取
    }
    
    std::string getAccountNumber() const {
        return "ACC123456789"; // 从配置或数据库中获取
    }
};

// 对象适配器:通过组合适配第三方支付系统
class ThirdPartyPaymentAdapter : public ModernPayment {
private:
    std::shared_ptr<ThirdPartyPayment> thirdPartyPayment_;
    std::string apiKey_;
    std::string merchantId_;
    
public:
    ThirdPartyPaymentAdapter(std::shared_ptr<ThirdPartyPayment> payment, 
                           const std::string& apiKey, const std::string& merchantId)
        : thirdPartyPayment_(payment), apiKey_(apiKey), merchantId_(merchantId) {}
    
    bool processPayment(double amount, const std::string& currency) override {
        std::cout << "🔄 第三方支付适配器: 转换支付请求..." << std::endl;
        
        // 转换货币
        double convertedAmount = convertCurrency(amount, currency, "USD");
        
        // 调用第三方支付方法
        return thirdPartyPayment_->sendPaymentRequest(convertedAmount, merchantId_, apiKey_);
    }
    
    std::string getPaymentMethod() const override {
        return "第三方支付 (" + thirdPartyPayment_->getMerchantInfo() + ")";
    }
    
    void refundPayment(const std::string& transactionId) override {
        std::cout << "🔄 第三方支付适配器: 转换退款请求..." << std::endl;
        // 在实际系统中,这里会有金额查询逻辑
        thirdPartyPayment_->initiateRefund(100.0, transactionId); // 假设退款100美元
    }
    
private:
    double convertCurrency(double amount, const std::string& from, const std::string& to) {
        // 简化的货币转换逻辑
        if (from == to) return amount;
        
        // 模拟汇率转换
        std::unordered_map<std::string, double> rates = {
            {"USD", 1.0},
            {"EUR", 0.85},
            {"GBP", 0.73},
            {"JPY", 110.0},
            {"CNY", 6.45}
        };
        
        if (rates.find(from) != rates.end() && rates.find(to) != rates.end()) {
            double converted = amount * (rates[to] / rates[from]);
            std::cout << "💱 货币转换: " << amount << " " << from << " -> " 
                      << converted << " " << to << std::endl;
            return converted;
        }
        
        std::cout << "⚠️ 不支持的货币转换: " << from << " -> " << to << std::endl;
        return amount;
    }
};

// 双向适配器:支持两个方向的适配
class BidirectionalPaymentAdapter : public ModernPayment {
private:
    std::shared_ptr<LegacyBankSystem> legacyBank_;
    std::shared_ptr<ThirdPartyPayment> thirdParty_;
    bool useLegacySystem_;
    
public:
    BidirectionalPaymentAdapter(std::shared_ptr<LegacyBankSystem> legacyBank,
                              std::shared_ptr<ThirdPartyPayment> thirdParty,
                              bool useLegacy = true)
        : legacyBank_(legacyBank), thirdParty_(thirdParty), useLegacySystem_(useLegacy) {}
    
    bool processPayment(double amount, const std::string& currency) override {
        if (useLegacySystem_) {
            std::cout << "🔄 双向适配器: 使用传统银行系统..." << std::endl;
            // 适配到传统银行系统
            int cents = static_cast<int>(amount * 100);
            return legacyBank_->makeBankPayment(cents, "BANK001", "ACC123456789");
        } else {
            std::cout << "🔄 双向适配器: 使用第三方支付系统..." << std::endl;
            // 适配到第三方支付系统
            return thirdParty_->sendPaymentRequest(amount, "MERCHANT001", "APIKEY123");
        }
    }
    
    std::string getPaymentMethod() const override {
        if (useLegacySystem_) {
            return "双向适配器 -> " + legacyBank_->getBankInfo();
        } else {
            return "双向适配器 -> " + thirdParty_->getMerchantInfo();
        }
    }
    
    void refundPayment(const std::string& transactionId) override {
        if (useLegacySystem_) {
            legacyBank_->processBankRefund(10000, transactionId);
        } else {
            thirdParty_->initiateRefund(100.0, transactionId);
        }
    }
    
    // 切换支付系统
    void switchPaymentSystem(bool useLegacy) {
        useLegacySystem_ = useLegacy;
        std::cout << "🔄 切换支付系统到: " << (useLegacy ? "传统银行" : "第三方支付") << std::endl;
    }
};

UML 武功秘籍图

adapts adapts adapts <<interface>> ModernPayment +processPayment(double, string) : bool +getPaymentMethod() : string +refundPayment(string) : void LegacyBankSystem -string bankCode_ -string accountNumber_ +makeBankPayment(int, string, string) : bool +processBankRefund(int, string) : void +getBankInfo() : string +validateAccount() : bool ThirdPartyPayment -string apiKey_ -string merchantId_ +sendPaymentRequest(double, string, string) : bool +initiateRefund(double, string) : bool +getMerchantInfo() : string BankPaymentAdapter +processPayment(double, string) : bool +getPaymentMethod() : string +refundPayment(string) : void -getBankCode() : string -getAccountNumber() : string ThirdPartyPaymentAdapter -shared_ptr<ThirdPartyPayment> thirdPartyPayment_ -string apiKey_ -string merchantId_ +processPayment(double, string) : bool +getPaymentMethod() : string +refundPayment(string) : void -convertCurrency(double, string, string) : double BidirectionalPaymentAdapter -shared_ptr<LegacyBankSystem> legacyBank_ -shared_ptr<ThirdPartyPayment> thirdParty_ -bool useLegacySystem_ +processPayment(double, string) : bool +getPaymentMethod() : string +refundPayment(string) : void +switchPaymentSystem(bool) : void

实战演练:多媒体格式转换系统

cpp 复制代码
#include <map>
#include <algorithm>

// 更复杂的适配器模式应用:多媒体系统

// 目标接口:现代媒体播放器
class MediaPlayer {
public:
    virtual ~MediaPlayer() = default;
    virtual void play(const std::string& audioType, const std::string& fileName) = 0;
    virtual void stop() = 0;
    virtual void setVolume(int level) = 0;
    virtual std::string getPlayerInfo() const = 0;
};

// 被适配者:高级音频播放器
class AdvancedAudioPlayer {
private:
    std::string currentFile_;
    bool isPlaying_;
    int volume_;
    
public:
    AdvancedAudioPlayer() : isPlaying_(false), volume_(50) {}
    
    // 支持高级音频格式
    void loadMp4Audio(const std::string& fileName) {
        currentFile_ = fileName;
        std::cout << "🎵 高级播放器加载 MP4 音频: " << fileName << std::endl;
    }
    
    void loadVlcAudio(const std::string& fileName) {
        currentFile_ = fileName;
        std::cout << "🎵 高级播放器加载 VLC 音频: " << fileName << std::endl;
    }
    
    void playAdvancedAudio() {
        if (!currentFile_.empty()) {
            isPlaying_ = true;
            std::cout << "▶️ 高级播放器播放: " << currentFile_ << std::endl;
        }
    }
    
    void stopAdvancedAudio() {
        if (isPlaying_) {
            isPlaying_ = false;
            std::cout << "⏹️ 高级播放器停止" << std::endl;
        }
    }
    
    void setAdvancedVolume(int level) {
        volume_ = std::clamp(level, 0, 100);
        std::cout << "🔊 高级播放器音量设置为: " << volume_ << std::endl;
    }
    
    std::string getSupportedFormats() const {
        return "MP4, VLC, AVI";
    }
};

// 被适配者:旧式磁带播放器
class CassettePlayer {
private:
    std::string currentTape_;
    bool isPlaying_;
    int volume_;
    
public:
    CassettePlayer() : isPlaying_(false), volume_(50) {}
    
    // 只能播放磁带
    void insertTape(const std::string& tapeName) {
        currentTape_ = tapeName;
        std::cout << "📼 插入磁带: " << tapeName << std::endl;
    }
    
    void playTape() {
        if (!currentTape_.empty()) {
            isPlaying_ = true;
            std::cout << "▶️ 磁带播放器播放: " << currentTape_ << std::endl;
        }
    }
    
    void stopTape() {
        if (isPlaying_) {
            isPlaying_ = false;
            std::cout << "⏹️ 磁带播放器停止" << std::endl;
        }
    }
    
    void setTapeVolume(int level) {
        volume_ = level;
        std::cout << "🔊 磁带播放器音量设置为: " << volume_ << std::endl;
    }
    
    void rewindTape() {
        std::cout << "⏪ 倒带..." << std::endl;
    }
    
    std::string getPlayerType() const {
        return "磁带播放器";
    }
};

// 被适配者:黑胶唱片机
class VinylPlayer {
private:
    std::string currentRecord_;
    bool isSpinning_;
    int volume_;
    
public:
    VinylPlayer() : isSpinning_(false), volume_(50) {}
    
    // 播放黑胶唱片
    void placeRecord(const std::string& recordName) {
        currentRecord_ = recordName;
        std::cout << "💿 放置黑胶唱片: " << recordName << std::endl;
    }
    
    void startSpinning() {
        if (!currentRecord_.empty()) {
            isSpinning_ = true;
            std::cout << "🌀 黑胶唱片机开始旋转: " << currentRecord_ << std::endl;
        }
    }
    
    void stopSpinning() {
        if (isSpinning_) {
            isSpinning_ = false;
            std::cout << "⏹️ 黑胶唱片机停止" << std::endl;
        }
    }
    
    void setNeedleVolume(int level) {
        volume_ = level;
        std::cout << "🔊 黑胶唱片机音量设置为: " << volume_ << std::endl;
    }
    
    void changeRotationSpeed(int rpm) {
        std::cout << "⚡ 调整转速: " << rpm << " RPM" << std::endl;
    }
    
    std::string getPlayerType() const {
        return "黑胶唱片机";
    }
};

// 媒体适配器:适配高级音频播放器
class AdvancedMediaAdapter : public MediaPlayer {
private:
    std::shared_ptr<AdvancedAudioPlayer> advancedPlayer_;
    std::string currentFormat_;
    
public:
    AdvancedMediaAdapter(std::shared_ptr<AdvancedAudioPlayer> player)
        : advancedPlayer_(player) {}
    
    void play(const std::string& audioType, const std::string& fileName) override {
        std::cout << "🔄 高级媒体适配器: 转换播放请求..." << std::endl;
        
        if (audioType == "mp4") {
            advancedPlayer_->loadMp4Audio(fileName);
            currentFormat_ = "mp4";
        } else if (audioType == "vlc") {
            advancedPlayer_->loadVlcAudio(fileName);
            currentFormat_ = "vlc";
        } else if (audioType == "avi") {
            advancedPlayer_->loadVlcAudio(fileName); // VLC 也支持 AVI
            currentFormat_ = "avi";
        } else {
            std::cout << "❌ 不支持的格式: " << audioType << std::endl;
            return;
        }
        
        advancedPlayer_->playAdvancedAudio();
    }
    
    void stop() override {
        advancedPlayer_->stopAdvancedAudio();
    }
    
    void setVolume(int level) override {
        advancedPlayer_->setAdvancedVolume(level);
    }
    
    std::string getPlayerInfo() const override {
        return "高级媒体适配器 -> " + advancedPlayer_->getSupportedFormats();
    }
};

// 传统媒体适配器:适配旧式播放设备
class LegacyMediaAdapter : public MediaPlayer {
private:
    std::shared_ptr<CassettePlayer> cassettePlayer_;
    std::shared_ptr<VinylPlayer> vinylPlayer_;
    bool useCassette_;
    
public:
    LegacyMediaAdapter(std::shared_ptr<CassettePlayer> cassette, 
                      std::shared_ptr<VinylPlayer> vinyl)
        : cassettePlayer_(cassette), vinylPlayer_(vinyl), useCassette_(true) {}
    
    void play(const std::string& audioType, const std::string& fileName) override {
        std::cout << "🔄 传统媒体适配器: 转换播放请求..." << std::endl;
        
        if (useCassette_) {
            // 模拟数字到模拟的转换
            std::cout << "💾 数字音频转换到磁带格式..." << std::endl;
            cassettePlayer_->insertTape("转换的磁带: " + fileName);
            cassettePlayer_->playTape();
        } else {
            // 模拟数字到黑胶的转换
            std::cout << "💾 数字音频转换到黑胶格式..." << std::endl;
            vinylPlayer_->placeRecord("转换的黑胶: " + fileName);
            vinylPlayer_->startSpinning();
        }
    }
    
    void stop() override {
        if (useCassette_) {
            cassettePlayer_->stopTape();
        } else {
            vinylPlayer_->stopSpinning();
        }
    }
    
    void setVolume(int level) override {
        if (useCassette_) {
            cassettePlayer_->setTapeVolume(level);
        } else {
            vinylPlayer_->setNeedleVolume(level);
        }
    }
    
    std::string getPlayerInfo() const override {
        if (useCassette_) {
            return "传统媒体适配器 -> " + cassettePlayer_->getPlayerType();
        } else {
            return "传统媒体适配器 -> " + vinylPlayer_->getPlayerType();
        }
    }
    
    // 切换播放设备
    void switchDevice(bool useCassette) {
        useCassette_ = useCassette;
        std::cout << "🔄 切换播放设备到: " << (useCassette ? "磁带播放器" : "黑胶唱片机") << std::endl;
    }
    
    // 传统设备特有功能
    void rewind() {
        if (useCassette_) {
            cassettePlayer_->rewindTape();
        }
    }
    
    void changeRotationSpeed(int rpm) {
        if (!useCassette_) {
            vinylPlayer_->changeRotationSpeed(rpm);
        }
    }
};

// 通用媒体适配器:支持多种格式和设备
class UniversalMediaAdapter : public MediaPlayer {
private:
    std::map<std::string, std::shared_ptr<MediaPlayer>> adapters_;
    std::string currentAdapter_;
    
public:
    void registerAdapter(const std::string& format, std::shared_ptr<MediaPlayer> adapter) {
        adapters_[format] = adapter;
        std::cout << "📝 注册媒体适配器: " << format << std::endl;
    }
    
    void play(const std::string& audioType, const std::string& fileName) override {
        auto it = adapters_.find(audioType);
        if (it != adapters_.end()) {
            currentAdapter_ = audioType;
            it->second->play(audioType, fileName);
        } else {
            std::cout << "❌ 没有找到支持格式 " << audioType << " 的适配器" << std::endl;
        }
    }
    
    void stop() override {
        if (!currentAdapter_.empty()) {
            adapters_[currentAdapter_]->stop();
        }
    }
    
    void setVolume(int level) override {
        if (!currentAdapter_.empty()) {
            adapters_[currentAdapter_]->setVolume(level);
        }
    }
    
    std::string getPlayerInfo() const override {
        if (!currentAdapter_.empty()) {
            return "通用媒体适配器 -> " + adapters_.at(currentAdapter_)->getPlayerInfo();
        }
        return "通用媒体适配器 (未选择适配器)";
    }
    
    // 获取支持的格式
    std::vector<std::string> getSupportedFormats() const {
        std::vector<std::string> formats;
        for (const auto& pair : adapters_) {
            formats.push_back(pair.first);
        }
        return formats;
    }
};

适配器模式的招式解析

招式一:参数适配器
cpp 复制代码
// 参数适配器:统一不同函数的参数格式
class ParameterAdapter {
public:
    // 统一不同日志系统的参数格式
    static std::string adaptLogMessage(const std::string& message, const std::string& level, 
                                      const std::string& source) {
        std::string timestamp = getCurrentTimestamp();
        return "[" + timestamp + "] [" + level + "] [" + source + "] " + message;
    }
    
    // 统一不同数据库查询的参数格式
    static std::string adaptSQLQuery(const std::string& table, 
                                    const std::map<std::string, std::string>& conditions,
                                    const std::vector<std::string>& columns) {
        std::string query = "SELECT ";
        
        if (columns.empty()) {
            query += "*";
        } else {
            for (size_t i = 0; i < columns.size(); ++i) {
                query += columns[i];
                if (i < columns.size() - 1) query += ", ";
            }
        }
        
        query += " FROM " + table;
        
        if (!conditions.empty()) {
            query += " WHERE ";
            size_t count = 0;
            for (const auto& condition : conditions) {
                query += condition.first + " = '" + condition.second + "'";
                if (++count < conditions.size()) query += " AND ";
            }
        }
        
        return query;
    }
    
private:
    static std::string getCurrentTimestamp() {
        // 返回当前时间戳(简化实现)
        return "2024-01-15 10:30:00";
    }
};

// 函数适配器:适配不同风格的函数接口
class FunctionAdapter {
public:
    // 适配C风格回调函数到现代C++风格
    template<typename Func, typename... Args>
    static auto adaptCFunction(Func cFunc, Args... args) {
        std::cout << "🔄 适配C风格函数到现代C++..." << std::endl;
        return cFunc(args...);
    }
    
    // 适配异常处理风格
    static bool adaptExceptionStyle(const std::function<void()>& func) {
        try {
            func();
            return true;
        } catch (const std::exception& e) {
            std::cout << "⚠️ 捕获异常: " << e.what() << std::endl;
            return false;
        }
    }
};
招式二:智能适配器工厂
cpp 复制代码
// 智能适配器工厂:根据上下文自动选择合适的适配器
class SmartAdapterFactory {
private:
    std::map<std::string, std::function<std::shared_ptr<MediaPlayer>()>> adapterCreators_;
    
public:
    SmartAdapterFactory() {
        initializeCreators();
    }
    
    void initializeCreators() {
        // 注册各种适配器的创建函数
        adapterCreators_["audio"] = []() {
            auto advancedPlayer = std::make_shared<AdvancedAudioPlayer>();
            return std::make_shared<AdvancedMediaAdapter>(advancedPlayer);
        };
        
        adapterCreators_["legacy"] = []() {
            auto cassette = std::make_shared<CassettePlayer>();
            auto vinyl = std::make_shared<VinylPlayer>();
            return std::make_shared<LegacyMediaAdapter>(cassette, vinyl);
        };
        
        adapterCreators_["universal"] = []() {
            auto universalAdapter = std::make_shared<UniversalMediaAdapter>();
            
            // 注册各种格式的适配器
            auto advancedPlayer = std::make_shared<AdvancedAudioPlayer>();
            auto advancedAdapter = std::make_shared<AdvancedMediaAdapter>(advancedPlayer);
            
            auto cassette = std::make_shared<CassettePlayer>();
            auto vinyl = std::make_shared<VinylPlayer>();
            auto legacyAdapter = std::make_shared<LegacyMediaAdapter>(cassette, vinyl);
            
            universalAdapter->registerAdapter("mp4", advancedAdapter);
            universalAdapter->registerAdapter("vlc", advancedAdapter);
            universalAdapter->registerAdapter("avi", advancedAdapter);
            universalAdapter->registerAdapter("cassette", legacyAdapter);
            universalAdapter->registerAdapter("vinyl", legacyAdapter);
            
            return universalAdapter;
        };
    }
    
    std::shared_ptr<MediaPlayer> createAdapter(const std::string& type) {
        auto it = adapterCreators_.find(type);
        if (it != adapterCreators_.end()) {
            std::cout << "🏭 创建智能适配器: " << type << std::endl;
            return it->second();
        }
        
        std::cout << "❌ 未知的适配器类型: " << type << std::endl;
        return nullptr;
    }
    
    std::vector<std::string> getAvailableAdapters() const {
        std::vector<std::string> types;
        for (const auto& pair : adapterCreators_) {
            types.push_back(pair.first);
        }
        return types;
    }
};

完整测试代码

cpp 复制代码
// 测试适配器模式
void testAdapterPattern() {
    std::cout << "=== 适配器模式测试开始 ===" << std::endl;
    
    // 测试支付系统适配器
    std::cout << "\n--- 支付系统适配器测试 ---" << std::endl;
    
    // 创建类适配器(银行支付)
    BankPaymentAdapter bankAdapter("ICBC", "6225880112345678");
    std::cout << "💳 支付方式: " << bankAdapter.getPaymentMethod() << std::endl;
    bankAdapter.processPayment(99.99, "USD");
    bankAdapter.refundPayment("TXN123456");
    
    // 创建对象适配器(第三方支付)
    auto thirdParty = std::make_shared<ThirdPartyPayment>("sk_test_123456789", "merchant_001");
    ThirdPartyPaymentAdapter thirdPartyAdapter(thirdParty, "sk_test_123456789", "merchant_001");
    std::cout << "\n💳 支付方式: " << thirdPartyAdapter.getPaymentMethod() << std::endl;
    thirdPartyAdapter.processPayment(149.99, "EUR");
    thirdPartyAdapter.refundPayment("pay_987654321");
    
    // 创建双向适配器
    auto legacyBank = std::make_shared<LegacyBankSystem>("CCB", "4367420012345678");
    auto thirdPartyPay = std::make_shared<ThirdPartyPayment>("sk_test_abcdef", "merchant_002");
    BidirectionalPaymentAdapter bidirectionalAdapter(legacyBank, thirdPartyPay, true);
    
    std::cout << "\n🔄 双向适配器测试:" << std::endl;
    std::cout << "支付方式: " << bidirectionalAdapter.getPaymentMethod() << std::endl;
    bidirectionalAdapter.processPayment(79.99, "USD");
    
    bidirectionalAdapter.switchPaymentSystem(false);
    std::cout << "支付方式: " << bidirectionalAdapter.getPaymentMethod() << std::endl;
    bidirectionalAdapter.processPayment(129.99, "GBP");
    
    // 测试媒体系统适配器
    std::cout << "\n--- 媒体系统适配器测试 ---" << std::endl;
    
    // 测试高级媒体适配器
    auto advancedPlayer = std::make_shared<AdvancedAudioPlayer>();
    AdvancedMediaAdapter advancedAdapter(advancedPlayer);
    
    std::cout << "🎵 媒体适配器: " << advancedAdapter.getPlayerInfo() << std::endl;
    advancedAdapter.play("mp4", "song.mp4");
    advancedAdapter.setVolume(75);
    advancedAdapter.stop();
    
    // 测试传统媒体适配器
    auto cassettePlayer = std::make_shared<CassettePlayer>();
    auto vinylPlayer = std::make_shared<VinylPlayer>();
    LegacyMediaAdapter legacyAdapter(cassettePlayer, vinylPlayer);
    
    std::cout << "\n🎵 传统媒体适配器测试:" << std::endl;
    std::cout << "播放器: " << legacyAdapter.getPlayerInfo() << std::endl;
    legacyAdapter.play("digital", "modern_song.mp3");
    legacyAdapter.setVolume(60);
    
    legacyAdapter.switchDevice(false);
    std::cout << "播放器: " << legacyAdapter.getPlayerInfo() << std::endl;
    legacyAdapter.play("digital", "classic_song.wav");
    legacyAdapter.stop();
    
    // 测试通用媒体适配器
    std::cout << "\n--- 通用媒体适配器测试 ---" << std::endl;
    UniversalMediaAdapter universalAdapter;
    
    // 注册适配器
    universalAdapter.registerAdapter("mp4", std::make_shared<AdvancedMediaAdapter>(
        std::make_shared<AdvancedAudioPlayer>()));
    
    universalAdapter.registerAdapter("cassette", std::make_shared<LegacyMediaAdapter>(
        std::make_shared<CassettePlayer>(), std::make_shared<VinylPlayer>()));
    
    // 测试不同格式
    universalAdapter.play("mp4", "video.mp4");
    std::cout << "当前适配器: " << universalAdapter.getPlayerInfo() << std::endl;
    
    universalAdapter.play("cassette", "mixtape.cas");
    std::cout << "当前适配器: " << universalAdapter.getPlayerInfo() << std::endl;
    
    // 测试参数适配器
    std::cout << "\n--- 参数适配器测试 ---" << std::endl;
    
    std::string logMessage = ParameterAdapter::adaptLogMessage("系统启动完成", "INFO", "System");
    std::cout << "📝 格式化日志: " << logMessage << std::endl;
    
    std::map<std::string, std::string> conditions = {{"name", "John"}, {"age", "30"}};
    std::vector<std::string> columns = {"id", "name", "email"};
    std::string sqlQuery = ParameterAdapter::adaptSQLQuery("users", conditions, columns);
    std::cout << "🗃️ 生成的SQL: " << sqlQuery << std::endl;
    
    // 测试智能适配器工厂
    std::cout << "\n--- 智能适配器工厂测试 ---" << std::endl;
    SmartAdapterFactory adapterFactory;
    
    auto availableAdapters = adapterFactory.getAvailableAdapters();
    std::cout << "可用的适配器类型: ";
    for (const auto& type : availableAdapters) {
        std::cout << type << " ";
    }
    std::cout << std::endl;
    
    auto universalMediaAdapter = adapterFactory.createAdapter("universal");
    if (universalMediaAdapter) {
        universalMediaAdapter->play("mp4", "movie.mp4");
        std::cout << "播放器信息: " << universalMediaAdapter->getPlayerInfo() << std::endl;
    }
    
    std::cout << "\n=== 适配器模式测试结束 ===" << std::endl;
}

// 实战应用:现代化改造系统
class ModernizationSystem {
private:
    SmartAdapterFactory adapterFactory_;
    
public:
    void demonstrateLegacyIntegration() {
        std::cout << "\n🔧 现代化改造系统演示" << std::endl;
        std::cout << "==========================" << std::endl;
        
        // 场景1:集成传统银行系统
        std::cout << "\n场景1: 集成传统银行系统到现代电商平台" << std::endl;
        integrateBankingSystem();
        
        // 场景2:统一多媒体播放
        std::cout << "\n场景2: 统一各种媒体格式播放" << std::endl;
        unifyMediaPlayback();
        
        // 场景3:多支付渠道集成
        std::cout << "\n场景3: 多支付渠道统一处理" << std::endl;
        integratePaymentChannels();
    }
    
private:
    void integrateBankingSystem() {
        // 模拟电商平台需要集成传统银行系统
        BankPaymentAdapter bankAdapter("BOC", "6013821000123456");
        
        std::cout << "🛒 用户下单购买商品,价格: $199.99" << std::endl;
        bool success = bankAdapter.processPayment(199.99, "USD");
        
        if (success) {
            std::cout << "✅ 支付成功!传统银行系统已通过适配器集成" << std::endl;
        }
    }
    
    void unifyMediaPlayback() {
        auto universalAdapter = adapterFactory_.createAdapter("universal");
        
        if (universalAdapter) {
            std::cout << "🎮 用户尝试播放各种格式的媒体文件:" << std::endl;
            
            std::vector<std::pair<std::string, std::string>> testFiles = {
                {"mp4", "trailer.mp4"},
                {"vlc", "music.vlc"},
                {"cassette", "retro_mix.cas"}
            };
            
            for (const auto& file : testFiles) {
                std::cout << "\n尝试播放: " << file.second << " (格式: " << file.first << ")" << std::endl;
                universalAdapter->play(file.first, file.second);
                std::cout << "使用的适配器: " << universalAdapter->getPlayerInfo() << std::endl;
                universalAdapter->stop();
            }
        }
    }
    
    void integratePaymentChannels() {
        std::cout << "💰 电商平台支持多种支付方式:" << std::endl;
        
        // 银行支付
        BankPaymentAdapter bankAdapter("CMB", "6226091000123456");
        std::cout << "1. " << bankAdapter.getPaymentMethod() << std::endl;
        
        // 第三方支付
        auto thirdParty = std::make_shared<ThirdPartyPayment>("sk_live_123456", "shop_001");
        ThirdPartyPaymentAdapter thirdPartyAdapter(thirdParty, "sk_live_123456", "shop_001");
        std::cout << "2. " << thirdPartyAdapter.getPaymentMethod() << std::endl;
        
        // 双向适配器
        auto legacyBank = std::make_shared<LegacyBankSystem>("ABC", "955991000123456");
        auto thirdPartyPay = std::make_shared<ThirdPartyPayment>("sk_live_abcdef", "shop_002");
        BidirectionalPaymentAdapter bidirectionalAdapter(legacyBank, thirdPartyPay, false);
        std::cout << "3. " << bidirectionalAdapter.getPaymentMethod() << std::endl;
        
        std::cout << "✅ 所有支付渠道已通过适配器统一集成" << std::endl;
    }
};

int main() {
    testAdapterPattern();
    
    // 运行现代化改造系统示例
    ModernizationSystem modernization;
    modernization.demonstrateLegacyIntegration();
    
    return 0;
}

适配器模式的武学心得

适用场景
  • 系统集成:集成第三方库或遗留系统时
  • 接口不兼容:现有类的接口与系统要求的接口不匹配时
  • 复用旧代码:想要复用一些现有的类,但其接口与系统的接口不一致
  • 统一接口:需要创建可复用的类,这些类与未知或未来相关的类协同工作
优点
  • 兼容性:让两个不兼容的接口能够一起工作
  • 复用性:可以复用现有的类,无需修改其源代码
  • 灵活性:可以动态切换不同的适配器
  • 单一职责:将接口转换代码与业务逻辑分离
缺点
  • 复杂度增加:增加了许多小的适配器类
  • 性能开销:额外的间接调用可能带来性能损失
  • 过度使用:如果接口设计合理,就不需要适配器

武林高手的点评

Prototype 赞叹道:"Adapter 兄的转接艺术确实精妙!能够如此优雅地解决接口不兼容的问题,这在系统集成时确实无人能及。"

Bridge 也点头称赞:"Adapter 兄专注于接口的兼容性转换,而我更关注抽象与实现的分离。我们各有所长,在不同的场景下发挥各自的优势。"

Adapter 谦虚回应:"诸位过奖了。每个模式都有其适用场景。在需要解决接口不兼容问题时,我的适配器模式确实能发挥重要作用。但在设计新的系统时,还是应该优先考虑良好的接口设计。"

下章预告

在Adapter展示完他的转接艺术后,Bridge 仙风道骨地走出,他手持一柄晶莹长桥作为法器,将桥往空中一抛,桥身便连接了抽象与实现两座虚无的山峰。

"Adapter兄是事后补救,老夫则是防患于未然。" Bridge抚须笑道,"下一章,我将展示如何将抽象与实现分离,让它们能够独立发展,互不掣肘!"

架构老人眼中露出赞许:"善!抽象与实现的分离确实是优秀设计的关键。下一章,就请 Bridge 展示他的桥梁构建之道!"


欲知 Bridge 如何通过桥接模式分离抽象与实现,且听下回分解!

相关推荐
charlie1145141913 小时前
精读C++20设计模式——结构型设计模式:外观模式
c++·学习·设计模式·c++20·外观模式
奔跑吧邓邓子3 小时前
【C++实战(58)】解锁C++内存优化密码:从泄漏检测到完美修复
c++·实战·内存优化
liulilittle3 小时前
macOS 内核路由表操作:直接 API 编程指南
网络·c++·macos·策略模式·路由·route·通信
辞旧 lekkk3 小时前
【c++】初识STL和string类
开发语言·c++·学习·萌新
爱和冰阔落4 小时前
【C++ STL栈和队列下】deque(双端队列) 优先级队列的模拟实现与仿函数的介绍
开发语言·数据结构·c++·算法·广度优先
想唱rap4 小时前
C++类和对象(2)
开发语言·c++·笔记·算法·新浪微博
fwerfv3453456 小时前
C++中的装饰器模式变体
开发语言·c++·算法
楼田莉子9 小时前
C++学习:C++11介绍及其新特性学习
开发语言·c++·学习·stl·visual studio
光电笑映12 小时前
C++list全解析
c语言·开发语言·数据结构·c++·list