第六章:适配器模式 - 接口转换的艺术大师
第六章:适配器模式 - 接口转换的艺术大师
故事延续:转接高手的兼容之道
在Prototype展示完他的克隆大法后,Adapter忙碌地走出,他身上挂着的各种转接头叮当作响。这位看起来最是忙碌的大师,一边走一边还在摆弄手中的工具。
"Prototype兄的克隆确实高效,"Adapter笑着说道,“但在软件江湖中,我们常常需要让不兼容的接口能够协同工作。我的武学核心在于——将一个类的接口转换成客户期望的另一个接口。让原本由于接口不兼容而不能一起工作的类可以一起工作!”
适配器模式的武学精要
核心心法
Adapter展示着他身上的各种转接头:“我的十二字真言是——兼容并包,转接万物。通过创建一个中间适配器类,我可以让两个不兼容的接口能够无缝协作,就像给不同规格的插头配上合适的转换器。”
C++ 代码实战
#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 武功秘籍图
实战演练:多媒体格式转换系统
#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 也支持 AVIcurrentFormat_ = "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;}
};
适配器模式的招式解析
招式一:参数适配器
// 参数适配器:统一不同函数的参数格式
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;}}
};
招式二:智能适配器工厂
// 智能适配器工厂:根据上下文自动选择合适的适配器
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;}
};
完整测试代码
// 测试适配器模式
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 如何通过桥接模式分离抽象与实现,且听下回分解!