适配器模式详解:概念、实现与应用
引言
适配器模式是一种结构型设计模式,它允许不兼容的接口协同工作。适配器模式将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。
什么是适配器模式?
适配器模式是一种结构型设计模式,它能让接口不兼容的对象能够相互合作。适配器模式充当两个不同接口之间的桥梁,将一个接口转换成另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。
核心思想
适配器模式的核心思想是:
- 接口转换:将一个接口转换成另一个接口
- 兼容性解决:解决接口不兼容的问题
- 复用现有代码:复用现有的类而不修改其源代码
为什么需要适配器模式?
在许多情况下,我们需要让不兼容的接口协同工作:
1. 集成第三方库
当需要集成第三方库但其接口与现有系统不兼容时:
- 第三方库使用不同的接口规范
- 需要将第三方库适配到现有系统中
- 避免修改现有系统的代码
2. 系统重构
当重构系统但需要保持向后兼容时:
- 保留旧接口以保持兼容性
- 提供新接口以支持新功能
- 逐步迁移现有代码
3. 多种实现的统一
当需要统一多种不同实现的接口时:
- 不同的数据库驱动程序
- 不同的消息队列实现
- 不同的支付网关接口
适配器模式的基本实现
让我们从一个简单的适配器模式实现开始:
javascript
// 目标接口(客户端期望的接口)
class Target {
request() {
return '目标接口的默认行为';
}
}
// 被适配者(不兼容的现有类)
class Adaptee {
specificRequest() {
return '被适配者的特殊行为';
}
}
// 适配器
class Adapter extends Target {
constructor(adaptee) {
super();
this.adaptee = adaptee;
}
request() {
const result = this.adaptee.specificRequest();
return `适配器: 转换 "${result}" 为目标接口格式`;
}
}
// 客户端代码
function clientCode(target) {
console.log(target.request());
}
console.log('客户端:我可以很好地处理目标对象:');
const target = new Target();
clientCode(target);
console.log('');
console.log('客户端:被适配者有一个奇怪的接口,我不理解:');
const adaptee = new Adaptee();
console.log(`被适配者: ${adaptee.specificRequest()}`);
console.log('');
console.log('客户端:但是可以通过适配器来处理它:');
const adapter = new Adapter(adaptee);
clientCode(adapter);实现要点分析
- 目标接口:客户端期望的接口
- 被适配者:需要适配的现有类
- 适配器:实现目标接口并包装被适配者
- 客户端:通过目标接口与适配器交互
适配器模式的实际应用场景
1. 支付网关适配器
在电商系统中,适配器模式非常适合用于统一不同支付网关的接口:
javascript
// 支付接口(目标接口)
class PaymentProcessor {
processPayment(amount, currency) {
throw new Error('必须实现 processPayment 方法');
}
refundPayment(transactionId, amount) {
throw new Error('必须实现 refundPayment 方法');
}
getTransactionStatus(transactionId) {
throw new Error('必须实现 getTransactionStatus 方法');
}
}
// 支付宝支付(被适配者)
class Alipay {
sendPayment(amount, currency) {
return {
success: true,
transactionId: `alipay_${Date.now()}`,
message: `支付宝支付 ${amount} ${currency} 成功`
};
}
sendRefund(transactionId, amount) {
return {
success: true,
refundId: `refund_${Date.now()}`,
message: `支付宝退款 ${amount} 成功`
};
}
checkOrderStatus(orderId) {
return {
status: 'completed',
message: `订单 ${orderId} 已完成`
};
}
}
// 微信支付(被适配者)
class WeChatPay {
makePayment(amount, currency) {
return {
result: 'SUCCESS',
out_trade_no: `wechat_${Date.now()}`,
return_msg: `微信支付 ${amount} ${currency} 成功`
};
}
refund(transationId, totalFee, refundFee) {
return {
result_code: 'SUCCESS',
refund_id: `refund_${Date.now()}`,
return_msg: `微信退款 ${refundFee} 成功`
};
}
queryOrder(outTradeNo) {
return {
trade_state: 'SUCCESS',
trade_state_desc: `订单 ${outTradeNo} 已支付`
};
}
}
// PayPal 支付(被适配者)
class PayPal {
createPayment(amount, currencyCode) {
return {
id: `paypal_${Date.now()}`,
state: 'approved',
message: `PayPal 支付 ${amount} ${currencyCode} 成功`
};
}
refundPayment(saleId, amount) {
return {
id: `paypal_refund_${Date.now()}`,
state: 'completed',
message: `PayPal 退款 $${amount} 成功`
};
}
getPaymentDetails(paymentId) {
return {
state: 'approved',
message: `支付 ${paymentId} 状态正常`
};
}
}
// 支付宝适配器
class AlipayAdapter extends PaymentProcessor {
constructor(alipay) {
super();
this.alipay = alipay;
}
processPayment(amount, currency) {
const result = this.alipay.sendPayment(amount, currency);
return {
success: result.success,
transactionId: result.transactionId,
message: result.message
};
}
refundPayment(transactionId, amount) {
const result = this.alipay.sendRefund(transactionId, amount);
return {
success: result.success,
refundId: result.refundId,
message: result.message
};
}
getTransactionStatus(transactionId) {
const result = this.alipay.checkOrderStatus(transactionId);
return {
status: result.status,
message: result.message
};
}
}
// 微信支付适配器
class WeChatPayAdapter extends PaymentProcessor {
constructor(wechatPay) {
super();
this.wechatPay = wechatPay;
}
processPayment(amount, currency) {
const result = this.wechatPay.makePayment(amount, currency);
return {
success: result.result === 'SUCCESS',
transactionId: result.out_trade_no,
message: result.return_msg
};
}
refundPayment(transactionId, amount) {
// 微信支付需要总费用和退款费用
const result = this.wechatPay.refund(transactionId, amount, amount);
return {
success: result.result_code === 'SUCCESS',
refundId: result.refund_id,
message: result.return_msg
};
}
getTransactionStatus(transactionId) {
const result = this.wechatPay.queryOrder(transactionId);
return {
status: result.trade_state,
message: result.trade_state_desc
};
}
}
// PayPal 适配器
class PayPalAdapter extends PaymentProcessor {
constructor(paypal) {
super();
this.paypal = paypal;
}
processPayment(amount, currency) {
const result = this.paypal.createPayment(amount, currency);
return {
success: result.state === 'approved',
transactionId: result.id,
message: result.message
};
}
refundPayment(transactionId, amount) {
const result = this.paypal.refundPayment(transactionId, amount);
return {
success: result.state === 'completed',
refundId: result.id,
message: result.message
};
}
getTransactionStatus(transactionId) {
const result = this.paypal.getPaymentDetails(transactionId);
return {
status: result.state,
message: result.message
};
}
}
// 支付服务管理器
class PaymentService {
constructor() {
this.processors = new Map();
}
registerProcessor(name, processor) {
this.processors.set(name, processor);
}
processPayment(processorName, amount, currency) {
const processor = this.processors.get(processorName);
if (!processor) {
throw new Error(`未找到支付处理器: ${processorName}`);
}
try {
const result = processor.processPayment(amount, currency);
console.log(`支付结果: ${result.message}`);
return result;
} catch (error) {
console.error(`支付失败: ${error.message}`);
return { success: false, message: error.message };
}
}
refundPayment(processorName, transactionId, amount) {
const processor = this.processors.get(processorName);
if (!processor) {
throw new Error(`未找到支付处理器: ${processorName}`);
}
try {
const result = processor.refundPayment(transactionId, amount);
console.log(`退款结果: ${result.message}`);
return result;
} catch (error) {
console.error(`退款失败: ${error.message}`);
return { success: false, message: error.message };
}
}
getTransactionStatus(processorName, transactionId) {
const processor = this.processors.get(processorName);
if (!processor) {
throw new Error(`未找到支付处理器: ${processorName}`);
}
try {
const result = processor.getTransactionStatus(transactionId);
console.log(`交易状态: ${result.message}`);
return result;
} catch (error) {
console.error(`查询状态失败: ${error.message}`);
return { status: 'error', message: error.message };
}
}
}
// 使用示例
function paymentExample() {
const paymentService = new PaymentService();
// 注册支付处理器
paymentService.registerProcessor('alipay', new AlipayAdapter(new Alipay()));
paymentService.registerProcessor('wechat', new WeChatPayAdapter(new WeChatPay()));
paymentService.registerProcessor('paypal', new PayPalAdapter(new PayPal()));
// 使用支付宝支付
console.log('=== 支付宝支付 ===');
const alipayResult = paymentService.processPayment('alipay', 100, 'CNY');
if (alipayResult.success) {
paymentService.getTransactionStatus('alipay', alipayResult.transactionId);
paymentService.refundPayment('alipay', alipayResult.transactionId, 50);
}
console.log('');
// 使用微信支付
console.log('=== 微信支付 ===');
const wechatResult = paymentService.processPayment('wechat', 200, 'CNY');
if (wechatResult.success) {
paymentService.getTransactionStatus('wechat', wechatResult.transactionId);
paymentService.refundPayment('wechat', wechatResult.transactionId, 100);
}
console.log('');
// 使用 PayPal 支付
console.log('=== PayPal 支付 ===');
const paypalResult = paymentService.processPayment('paypal', 50, 'USD');
if (paypalResult.success) {
paymentService.getTransactionStatus('paypal', paypalResult.transactionId);
paymentService.refundPayment('paypal', paypalResult.transactionId, 25);
}
}
paymentExample();2. 数据库驱动适配器
在数据库访问层中,适配器模式非常适合用于统一不同数据库的接口:
javascript
// 数据库接口(目标接口)
class Database {
connect() {
throw new Error('必须实现 connect 方法');
}
query(sql, params = []) {
throw new Error('必须实现 query 方法');
}
execute(sql, params = []) {
throw new Error('必须实现 execute 方法');
}
close() {
throw new Error('必须实现 close 方法');
}
}
// MySQL 驱动(被适配者)
class MySQLDriver {
constructor(options) {
this.host = options.host;
this.port = options.port;
this.user = options.user;
this.password = options.password;
this.database = options.database;
this.connected = false;
}
createConnection() {
console.log(`MySQL: 连接到 ${this.host}:${this.port}`);
this.connected = true;
return { connectionId: 'mysql_conn_1' };
}
executeQuery(query, values) {
if (!this.connected) {
throw new Error('MySQL: 未连接到数据库');
}
console.log(`MySQL: 执行查询 "${query}" with values:`, values);
return {
rows: [
{ id: 1, name: '用户1', email: 'user1@example.com' },
{ id: 2, name: '用户2', email: 'user2@example.com' }
],
rowCount: 2
};
}
executeUpdate(sql, values) {
if (!this.connected) {
throw new Error('MySQL: 未连接到数据库');
}
console.log(`MySQL: 执行更新 "${sql}" with values:`, values);
return { affectedRows: 1, insertId: 3 };
}
endConnection() {
console.log('MySQL: 关闭连接');
this.connected = false;
}
}
// PostgreSQL 驱动(被适配者)
class PostgreSQLDriver {
constructor(config) {
this.host = config.host;
this.port = config.port;
this.username = config.username;
this.password = config.password;
this.dbname = config.dbname;
this.client = null;
}
connect() {
console.log(`PostgreSQL: 连接到 ${this.host}:${this.port}`);
this.client = { id: 'pg_client_1' };
return this.client;
}
queryDatabase(text, parameters) {
if (!this.client) {
throw new Error('PostgreSQL: 未连接到数据库');
}
console.log(`PostgreSQL: 执行查询 "${text}" with parameters:`, parameters);
return {
rows: [
{ id: 1, name: '用户A', email: 'userA@example.com' },
{ id: 2, name: '用户B', email: 'userB@example.com' }
],
rowCount: 2
};
}
executeSQL(text, parameters) {
if (!this.client) {
throw new Error('PostgreSQL: 未连接到数据库');
}
console.log(`PostgreSQL: 执行更新 "${text}" with parameters:`, parameters);
return { rowCount: 1 };
}
disconnect() {
console.log('PostgreSQL: 关闭连接');
this.client = null;
}
}
// MongoDB 驱动(被适配者)
class MongoDBDriver {
constructor(url, options) {
this.url = url;
this.options = options;
this.client = null;
this.db = null;
}
connectToMongo() {
console.log(`MongoDB: 连接到 ${this.url}`);
this.client = { id: 'mongo_client_1' };
this.db = { name: 'testdb' };
return this.client;
}
findDocuments(collection, query, options) {
if (!this.client) {
throw new Error('MongoDB: 未连接到数据库');
}
console.log(`MongoDB: 在集合 ${collection} 中查找文档,查询:`, query, '选项:', options);
return [
{ _id: '1', name: '文档1', email: 'doc1@example.com' },
{ _id: '2', name: '文档2', email: 'doc2@example.com' },
];
}
updateDocuments(collection, filter, update, options) {
if (!this.client) {
throw new Error('MongoDB: 未连接到数据库');
}
console.log(`MongoDB: 更新集合 ${collection} 中的文档,过滤器:`, filter, '更新:', update);
return { modifiedCount: 1, matchedCount: 1 };
}
closeConnection() {
console.log('MongoDB: 关闭连接');
this.client = null;
this.db = null;
}
}
// MySQL 适配器
class MySQLAdapter extends Database {
constructor(options) {
super();
this.driver = new MySQLDriver(options);
}
connect() {
return this.driver.createConnection();
}
query(sql, params = []) {
return this.driver.executeQuery(sql, params);
}
execute(sql, params = []) {
return this.driver.executeUpdate(sql, params);
}
close() {
this.driver.endConnection();
}
}
// PostgreSQL 适配器
class PostgreSQLAdapter extends Database {
constructor(config) {
super();
this.driver = new PostgreSQLDriver(config);
}
connect() {
return this.driver.connect();
}
query(sql, params = []) {
return this.driver.queryDatabase(sql, params);
}
execute(sql, params = []) {
return this.driver.executeSQL(sql, params);
}
close() {
this.driver.disconnect();
}
}
// MongoDB 适配器
class MongoDBAdapter extends Database {
constructor(url, options) {
super();
this.driver = new MongoDBDriver(url, options);
}
connect() {
return this.driver.connectToMongo();
}
query(sql, params = []) {
// 将 SQL 查询转换为 MongoDB 查询
const collection = sql.match(/FROM\s+(\w+)/i)?.[1] || 'default';
const query = params.length > 0 ? { _id: params[0] } : {};
return this.driver.findDocuments(collection, query, {});
}
execute(sql, params = []) {
// 将 SQL 更新转换为 MongoDB 更新
const collection = sql.match(/UPDATE\s+(\w+)/i)?.[1] || 'default';
const filter = params.length > 1 ? { _id: params[0] } : {};
const update = params.length > 1 ? { $set: params[1] } : {};
return this.driver.updateDocuments(collection, filter, update, {});
}
close() {
this.driver.closeConnection();
}
}
// 数据库管理器
class DatabaseManager {
constructor() {
this.connections = new Map();
}
connect(dbType, config) {
let database;
switch (dbType) {
case 'mysql':
database = new MySQLAdapter(config);
break;
case 'postgresql':
database = new PostgreSQLAdapter(config);
break;
case 'mongodb':
database = new MongoDBAdapter(config.url, config.options);
break;
default:
throw new Error(`不支持的数据库类型: ${dbType}`);
}
database.connect();
this.connections.set(dbType, database);
return database;
}
query(dbType, sql, params = []) {
const database = this.connections.get(dbType);
if (!database) {
throw new Error(`未找到数据库连接: ${dbType}`);
}
return database.query(sql, params);
}
execute(dbType, sql, params = []) {
const database = this.connections.get(dbType);
if (!database) {
throw new Error(`未找到数据库连接: ${dbType}`);
}
return database.execute(sql, params);
}
close(dbType) {
const database = this.connections.get(dbType);
if (database) {
database.close();
this.connections.delete(dbType);
}
}
closeAll() {
for (const [dbType, database] of this.connections) {
try {
database.close();
} catch (error) {
console.error(`关闭 ${dbType} 连接时出错:`, error.message);
}
}
this.connections.clear();
}
}
// 使用示例
function databaseExample() {
const dbManager = new DatabaseManager();
// 连接 MySQL
console.log('=== 连接 MySQL ===');
const mysqlConfig = {
host: 'localhost',
port: 3306,
user: 'root',
password: 'password',
database: 'testdb'
};
try {
dbManager.connect('mysql', mysqlConfig);
const mysqlUsers = dbManager.query('mysql', 'SELECT * FROM users WHERE id = ?', [1]);
console.log('MySQL 查询结果:', mysqlUsers);
const mysqlUpdate = dbManager.execute('mysql', 'UPDATE users SET name = ? WHERE id = ?', ['新名字', 1]);
console.log('MySQL 更新结果:', mysqlUpdate);
} catch (error) {
console.error('MySQL 操作失败:', error.message);
}
console.log('');
// 连接 PostgreSQL
console.log('=== 连接 PostgreSQL ===');
const pgConfig = {
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'password',
dbname: 'testdb'
};
try {
dbManager.connect('postgresql', pgConfig);
const pgUsers = dbManager.query('postgresql', 'SELECT * FROM users WHERE id = $1', [1]);
console.log('PostgreSQL 查询结果:', pgUsers);
const pgUpdate = dbManager.execute('postgresql', 'UPDATE users SET name = $1 WHERE id = $2', ['新名字', 1]);
console.log('PostgreSQL 更新结果:', pgUpdate);
} catch (error) {
console.error('PostgreSQL 操作失败:', error.message);
}
console.log('');
// 连接 MongoDB
console.log('=== 连接 MongoDB ===');
const mongoConfig = {
url: 'mongodb://localhost:27017',
options: { useNewUrlParser: true }
};
try {
dbManager.connect('mongodb', mongoConfig);
const mongoDocs = dbManager.query('mongodb', 'SELECT * FROM users', ['1']);
console.log('MongoDB 查询结果:', mongoDocs);
const mongoUpdate = dbManager.execute('mongodb', 'UPDATE users', ['1', { name: '新名字' }]);
console.log('MongoDB 更新结果:', mongoUpdate);
} catch (error) {
console.error('MongoDB 操作失败:', error.message);
}
// 关闭所有连接
console.log('');
console.log('=== 关闭所有连接 ===');
dbManager.closeAll();
}
databaseExample();3. API 客户端适配器
在微服务架构中,适配器模式非常适合用于统一不同服务的 API 接口:
javascript
// API 客户端接口(目标接口)
class APIClient {
get(endpoint, params = {}) {
throw new Error('必须实现 get 方法');
}
post(endpoint, data = {}) {
throw new Error('必须实现 post 方法');
}
put(endpoint, data = {}) {
throw new Error('必须实现 put 方法');
}
delete(endpoint) {
throw new Error('必须实现 delete 方法');
}
setAuthToken(token) {
throw new Error('必须实现 setAuthToken 方法');
}
}
// REST API 客户端(被适配者)
class RESTClient {
constructor(baseUrl) {
this.baseUrl = baseUrl;
this.headers = {
'Content-Type': 'application/json'
};
}
setHeader(key, value) {
this.headers[key] = value;
}
async makeRequest(method, url, data = null) {
const fullUrl = `${this.baseUrl}${url}`;
const options = {
method,
headers: { ...this.headers }
};
if (data) {
options.body = JSON.stringify(data);
}
console.log(`REST: ${method} ${fullUrl}`, data ? `with data: ${JSON.stringify(data)}` : '');
// 模拟 API 响应
return new Promise(resolve => {
setTimeout(() => {
const response = {
status: 200,
data: { message: `REST ${method} 请求成功`, url, data }
};
resolve(response);
}, 100);
});
}
async get(url, params = {}) {
const queryString = new URLSearchParams(params).toString();
const fullUrl = queryString ? `${url}?${queryString}` : url;
return this.makeRequest('GET', fullUrl);
}
async post(url, data = {}) {
return this.makeRequest('POST', url, data);
}
async put(url, data = {}) {
return this.makeRequest('PUT', url, data);
}
async delete(url) {
return this.makeRequest('DELETE', url);
}
}
// GraphQL 客户端(被适配者)
class GraphQLClient {
constructor(endpoint) {
this.endpoint = endpoint;
this.headers = {
'Content-Type': 'application/json'
};
}
setHeader(key, value) {
this.headers[key] = value;
}
async query(query, variables = {}) {
console.log(`GraphQL: Query ${query}`, variables ? `with variables: ${JSON.stringify(variables)}` : '');
// 模拟 GraphQL 响应
return new Promise(resolve => {
setTimeout(() => {
const response = {
data: { message: 'GraphQL 查询成功', query, variables }
};
resolve(response);
}, 100);
});
}
async mutate(mutation, variables = {}) {
console.log(`GraphQL: Mutation ${mutation}`, variables ? `with variables: ${JSON.stringify(variables)}` : '');
// 模拟 GraphQL 响应
return new Promise(resolve => {
setTimeout(() => {
const response = {
data: { message: 'GraphQL 变更成功', mutation, variables }
};
resolve(response);
}, 100);
});
}
}
// gRPC 客户端(被适配者)
class GRPCClient {
constructor(serviceUrl) {
this.serviceUrl = serviceUrl;
this.metadata = new Map();
}
setMetadata(key, value) {
this.metadata.set(key, value);
}
async unaryCall(method, request) {
console.log(`gRPC: 调用方法 ${method}`, request ? `with request: ${JSON.stringify(request)}` : '');
// 模拟 gRPC 响应
return new Promise(resolve => {
setTimeout(() => {
const response = {
message: `gRPC 调用 ${method} 成功`,
method,
request
};
resolve(response);
}, 100);
});
}
async serverStreamingCall(method, request) {
console.log(`gRPC: 服务器流式调用方法 ${method}`, request ? `with request: ${JSON.stringify(request)}` : '');
// 模拟 gRPC 流式响应
return new Promise(resolve => {
setTimeout(() => {
const response = {
messages: [
{ message: `gRPC 流式响应 1`, method, request },
{ message: `gRPC 流式响应 2`, method, request },
{ message: `gRPC 流式响应 3`, method, request }
]
};
resolve(response);
}, 100);
});
}
}
// REST API 适配器
class RESTAdapter extends APIClient {
constructor(baseUrl) {
super();
this.client = new RESTClient(baseUrl);
}
async get(endpoint, params = {}) {
return this.client.get(endpoint, params);
}
async post(endpoint, data = {}) {
return this.client.post(endpoint, data);
}
async put(endpoint, data = {}) {
return this.client.put(endpoint, data);
}
async delete(endpoint) {
return this.client.delete(endpoint);
}
setAuthToken(token) {
this.client.setHeader('Authorization', `Bearer ${token}`);
}
}
// GraphQL 适配器
class GraphQLAdapter extends APIClient {
constructor(endpoint) {
super();
this.client = new GraphQLClient(endpoint);
}
async get(endpoint, params = {}) {
const query = `query { ${endpoint.replace('/', '')} { ${Object.keys(params).join(' ')} } }`;
return this.client.query(query, params);
}
async post(endpoint, data = {}) {
const mutation = `mutation { ${endpoint.replace('/', '')} { ${Object.keys(data).join(' ')} } }`;
return this.client.mutate(mutation, data);
}
async put(endpoint, data = {}) {
return this.post(endpoint, data);
}
async delete(endpoint) {
const mutation = `mutation { delete${endpoint.replace('/', '').charAt(0).toUpperCase() + endpoint.replace('/', '').slice(1)} }`;
return this.client.mutate(mutation);
}
setAuthToken(token) {
this.client.setHeader('Authorization', `Bearer ${token}`);
}
}
// gRPC 适配器
class GRPCAdapter extends APIClient {
constructor(serviceUrl) {
super();
this.client = new GRPCClient(serviceUrl);
}
async get(endpoint, params = {}) {
const method = `Get${endpoint.replace('/', '').charAt(0).toUpperCase() + endpoint.replace('/', '').slice(1)}`;
return this.client.unaryCall(method, params);
}
async post(endpoint, data = {}) {
const method = `Create${endpoint.replace('/', '').charAt(0).toUpperCase() + endpoint.replace('/', '').slice(1)}`;
return this.client.unaryCall(method, data);
}
async put(endpoint, data = {}) {
const method = `Update${endpoint.replace('/', '').charAt(0).toUpperCase() + endpoint.replace('/', '').slice(1)}`;
return this.client.unaryCall(method, data);
}
async delete(endpoint) {
const method = `Delete${endpoint.replace('/', '').charAt(0).toUpperCase() + endpoint.replace('/', '').slice(1)}`;
return this.client.unaryCall(method);
}
setAuthToken(token) {
this.client.setMetadata('authorization', `Bearer ${token}`);
}
}
// API 客户端管理器
class APIClientManager {
constructor() {
this.clients = new Map();
}
registerClient(name, client) {
this.clients.set(name, client);
}
getClient(name) {
const client = this.clients.get(name);
if (!client) {
throw new Error(`未找到 API 客户端: ${name}`);
}
return client;
}
async request(clientName, method, endpoint, data = {}) {
const client = this.getClient(clientName);
try {
let response;
switch (method.toLowerCase()) {
case 'get':
response = await client.get(endpoint, data);
break;
case 'post':
response = await client.post(endpoint, data);
break;
case 'put':
response = await client.put(endpoint, data);
break;
case 'delete':
response = await client.delete(endpoint);
break;
default:
throw new Error(`不支持的 HTTP 方法: ${method}`);
}
console.log(`API 调用成功: ${clientName} ${method} ${endpoint}`);
return response;
} catch (error) {
console.error(`API 调用失败: ${clientName} ${method} ${endpoint}`, error.message);
throw error;
}
}
setAuthToken(clientName, token) {
const client = this.getClient(clientName);
client.setAuthToken(token);
}
}
// 使用示例
async function apiClientExample() {
const apiManager = new APIClientManager();
// 注册不同类型的 API 客户端
apiManager.registerClient('rest', new RESTAdapter('https://api.rest-example.com'));
apiManager.registerClient('graphql', new GraphQLAdapter('https://api.graphql-example.com/graphql'));
apiManager.registerClient('grpc', new GRPCAdapter('https://api.grpc-example.com'));
// 设置认证令牌
apiManager.setAuthToken('rest', 'rest_token_123');
apiManager.setAuthToken('graphql', 'graphql_token_456');
apiManager.setAuthToken('grpc', 'grpc_token_789');
console.log('=== REST API 调用 ===');
try {
const restUsers = await apiManager.request('rest', 'get', '/users', { page: 1, limit: 10 });
console.log('REST 响应:', restUsers);
const restCreateUser = await apiManager.request('rest', 'post', '/users', { name: '新用户', email: 'newuser@example.com' });
console.log('REST 创建用户响应:', restCreateUser);
} catch (error) {
console.error('REST API 调用失败:', error.message);
}
console.log('');
console.log('=== GraphQL API 调用 ===');
try {
const graphqlUsers = await apiManager.request('graphql', 'get', '/users', { id: 1, name: true, email: true });
console.log('GraphQL 响应:', graphqlUsers);
const graphqlCreateUser = await apiManager.request('graphql', 'post', '/users', { name: '新用户', email: 'newuser@example.com' });
console.log('GraphQL 创建用户响应:', graphqlCreateUser);
} catch (error) {
console.error('GraphQL API 调用失败:', error.message);
}
console.log('');
console.log('=== gRPC API 调用 ===');
try {
const grpcUsers = await apiManager.request('grpc', 'get', '/users', { id: 1 });
console.log('gRPC 响应:', grpcUsers);
const grpcCreateUser = await apiManager.request('grpc', 'post', '/users', { name: '新用户', email: 'newuser@example.com' });
console.log('gRPC 创建用户响应:', grpcCreateUser);
} catch (error) {
console.error('gRPC API 调用失败:', error.message);
}
}
// 运行示例
apiClientExample();适配器模式的两种实现方式
类适配器
类适配器通过继承来实现适配:
javascript
// 类适配器示例
class ClassAdapter extends Target {
constructor(adaptee) {
super();
this.adaptee = adaptee;
}
request() {
// 调用被适配者的方法并转换结果
return this.adaptee.specificRequest().toUpperCase();
}
}对象适配器
对象适配器通过组合来实现适配:
javascript
// 对象适配器示例
class ObjectAdapter {
constructor(adaptee) {
this.adaptee = adaptee;
}
request() {
// 调用被适配者的方法并转换结果
return this.adaptee.specificRequest().toLowerCase();
}
}适配器模式与其它模式的对比
适配器模式 vs 装饰器模式
javascript
// 适配器模式 - 改变接口
class Adapter {
constructor(adaptee) {
this.adaptee = adaptee;
}
newMethod() {
return this.adaptee.oldMethod();
}
}
// 装饰器模式 - 增强功能
class Decorator {
constructor(component) {
this.component = component;
}
operation() {
// 增强原有功能
return `装饰后: ${this.component.operation()}`;
}
}适配器模式 vs 外观模式
javascript
// 适配器模式 - 转换单个接口
class Adapter {
request() {
return this.adaptee.specificRequest();
}
}
// 外观模式 - 简化复杂子系统
class Facade {
operation() {
this.subsystem1.operation1();
this.subsystem2.operation2();
this.subsystem3.operation3();
}
}适配器模式的优缺点
优点
- 单一职责原则:可以将接口或数据转换代码从主要业务逻辑中分离
- 开闭原则:只要客户端代码通过目标接口与适配器进行交互,就能在不修改现有客户端代码的情况下添加新类型的适配器
- 复用现有代码:可以复用现有的类,即使它们的接口与所需接口不兼容
- 灵活性:可以在运行时切换适配器,实现不同的行为
缺点
- 复杂性增加:代码整体复杂度增加,因为需要新增一些接口和类
- 适配器泛滥:过度使用适配器会让系统变得凌乱,难以维护
- 性能开销:适配器在转换过程中可能会带来一些性能开销
总结
适配器模式是一种结构型设计模式,它允许不兼容的接口协同工作。适配器模式通过创建一个适配器类来解决接口不兼容的问题,使得原本由于接口不兼容而不能一起工作的类可以一起工作。
通过本章的学习,我们了解了:
- 适配器模式的基本概念和核心思想
- 适配器模式的实现方式(类适配器和对象适配器)
- 适配器模式在实际开发中的应用场景(支付网关、数据库驱动、API客户端)
- 适配器模式与其他结构型模式的对比
- 适配器模式的优缺点
适配器模式在现代软件开发中应用广泛,特别是在需要集成第三方库、重构遗留系统或统一多种实现接口的场景中,它可以很好地解决接口不兼容的问题。
在下一章中,我们将继续探讨其他结构型模式,首先是装饰器模式。