第六章:适配器模式 - 接口转换的艺术大师
故事延续:转接高手的兼容之道
在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 如何通过桥接模式分离抽象与实现,且听下回分解!