深入理解设计模式之适配器模式
深入理解设计模式之适配器模式(Adapter Pattern)
一、引言
在软件开发中,我们经常遇到这样的问题:已有的类接口与需要的接口不匹配。比如你有一个欧标插头的电器,但酒店只提供美标插座;或者你需要整合一个第三方SDK,但它的接口与你的系统不兼容。这时,适配器模式就派上用场了。
适配器模式就像现实中的电源转换器,它充当两个不兼容接口之间的桥梁,使得原本无法协同工作的类可以一起工作。本文将深入探讨适配器模式的原理、实现方式,并结合Spring、JDBC等实际框架应用,帮助你全面掌握这一重要的设计模式。
二、什么是适配器模式
2.1 定义
适配器模式(Adapter Pattern)是一种结构型设计模式,它将一个类的接口转换成客户端期望的另一个接口。适配器让原本接口不兼容的类可以相互合作。
2.2 核心思想
- 接口转换:将一个接口转换为另一个接口
- 复用现有类:不修改现有代码的前提下实现兼容
- 解耦:客户端与被适配者解耦
- 两个方向:可以将新接口适配到旧系统,也可以将旧接口适配到新系统
2.3 模式结构
客户端使用的接口: ┌──────────────────────┐ │ <<interface>> │ │ Target │ 目标接口(客户端期望的) ├──────────────────────┤ │ + request() │ └──────────────────────┘ △ │ 实现 │ ┌─────┴──────────────────┐ │ │ ┌────┴────────┐ ┌────────┴─────────┐ │ Adapter │ │ Adaptee │ 被适配者(已存在的类) ├─────────────┤ ├──────────────────┤ │- adaptee │◆────→│+ specificRequest │ 特殊的方法 │+ request() │ └──────────────────┘ └─────────────┘ │ └→ 调用adaptee.specificRequest()
2.4 适配器模式的三种形式
1. 类适配器(使用继承):
┌───────────┐ ┌──────────┐ │ Target │ │ Adaptee │ └─────△─────┘ └────△─────┘ │ │ │ │ └────┬────────────┘ │ 多重继承 ┌────┴─────┐ │ Adapter │ └──────────┘ 注:Java不支持多重继承,所以通常使用接口+类继承
2. 对象适配器(使用组合,推荐):
┌───────────┐ ┌──────────┐ │ Target │ │ Adaptee │ └─────△─────┘ └──────────┘ │ △ │ │组合 │ ┌────┴─────┐ │ │ │ └────────────┤ Adapter │ └──────────┘
3. 接口适配器(缺省适配器):
┌────────────────────┐ │ <<interface>> │ │ MultiMethod │ 多方法接口 ├────────────────────┤ │+ method1() │ │+ method2() │ │+ method3() │ │+ method4() │ └─────────△──────────┘ │ ┌─────┴─────┐ │ Abstract │ 抽象适配器(提供空实现) │ Adapter │ └─────△─────┘ │ │ ┌─────┴──────┐ │ Concrete │ 具体类只需实现需要的方法 │ Adapter │ └────────────┘
三、基础示例
3.1 场景:电源适配器
最经典的例子:中国电器(220V)需要在日本(110V)使用。
目标接口(客户端期望):
/** * 目标接口:日本电源插座(110V) */ public interface JapanesePlug { /** * 提供110V电压 */ void provide110V(); }
被适配者(已存在的类):
/** * 被适配者:中国电器(需要220V) */ public class ChineseAppliance { private String name; public ChineseAppliance(String name) { this.name = name; } /** * 使用220V电压工作 */ public void use220V() { System.out.println(name + " 正在使用220V电压工作"); } public String getName() { return name; } }
对象适配器:
/** * 对象适配器:电源适配器(推荐方式) * 将220V的中国电器适配到110V的日本插座 */ public class PowerAdapter implements JapanesePlug { private ChineseAppliance chineseAppliance; public PowerAdapter(ChineseAppliance chineseAppliance) { this.chineseAppliance = chineseAppliance; } @Override public void provide110V() { System.out.println("电源适配器工作中:将110V转换为220V"); // 调用被适配者的方法 chineseAppliance.use220V(); } }
类适配器(Java中使用接口+继承):
/** * 类适配器:通过继承实现适配 */ public class PowerAdapterByInheritance extends ChineseAppliance implements JapanesePlug { public PowerAdapterByInheritance(String name) { super(name); } @Override public void provide110V() { System.out.println("电源适配器工作中(类适配器):将110V转换为220V"); // 直接调用父类方法 use220V(); } }
客户端使用:
public class PowerAdapterDemo { public static void main(String[] args) { System.out.println("=== 场景1:使用对象适配器 ==="); // 中国电器 ChineseAppliance laptop = new ChineseAppliance("笔记本电脑"); // 使用适配器,让中国电器在日本使用 JapanesePlug adapter = new PowerAdapter(laptop); adapter.provide110V(); System.out.println("\n=== 场景2:使用类适配器 ==="); JapanesePlug adapter2 = new PowerAdapterByInheritance("电吹风"); adapter2.provide110V(); } }
输出:
=== 场景1:使用对象适配器 === 电源适配器工作中:将110V转换为220V 笔记本电脑 正在使用220V电压工作 === 场景2:使用类适配器 === 电源适配器工作中(类适配器):将110V转换为220V 电吹风 正在使用220V电压工作
3.2 场景:读卡器(多种适配器)
读卡器可以读取不同类型的存储卡。
/** * 目标接口:通用存储设备 */ public interface StorageDevice { String readData(); void writeData(String data); } /** * 被适配者1:SD卡 */ public class SDCard { public String readSD() { return "SD卡数据"; } public void writeSD(String data) { System.out.println("写入SD卡: " + data); } } /** * 被适配者2:TF卡(Micro SD) */ public class TFCard { public String readTF() { return "TF卡数据"; } public void writeTF(String data) { System.out.println("写入TF卡: " + data); } } /** * 被适配者3:Memory Stick */ public class MemoryStick { public String readMS() { return "Memory Stick数据"; } public void writeMS(String data) { System.out.println("写入Memory Stick: " + data); } } /** * SD卡适配器 */ public class SDCardAdapter implements StorageDevice { private SDCard sdCard; public SDCardAdapter(SDCard sdCard) { this.sdCard = sdCard; } @Override public String readData() { return sdCard.readSD(); } @Override public void writeData(String data) { sdCard.writeSD(data); } } /** * TF卡适配器 */ public class TFCardAdapter implements StorageDevice { private TFCard tfCard; public TFCardAdapter(TFCard tfCard) { this.tfCard = tfCard; } @Override public String readData() { return tfCard.readTF(); } @Override public void writeData(String data) { tfCard.writeTF(data); } } /** * Memory Stick适配器 */ public class MemoryStickAdapter implements StorageDevice { private MemoryStick memoryStick; public MemoryStickAdapter(MemoryStick memoryStick) { this.memoryStick = memoryStick; } @Override public String readData() { return memoryStick.readMS(); } @Override public void writeData(String data) { memoryStick.writeMS(data); } } /** * 客户端:电脑(只认识通用存储设备接口) */ public class Computer { public void readStorage(StorageDevice storage) { String data = storage.readData(); System.out.println("电脑读取到: " + data); } public void writeStorage(StorageDevice storage, String data) { storage.writeData(data); System.out.println("电脑写入完成"); } } /** * 测试类 */ public class CardReaderDemo { public static void main(String[] args) { Computer computer = new Computer(); // 使用SD卡 System.out.println("=== 使用SD卡 ==="); SDCard sdCard = new SDCard(); StorageDevice sdAdapter = new SDCardAdapter(sdCard); computer.readStorage(sdAdapter); computer.writeStorage(sdAdapter, "文档.doc"); // 使用TF卡 System.out.println("\n=== 使用TF卡 ==="); TFCard tfCard = new TFCard(); StorageDevice tfAdapter = new TFCardAdapter(tfCard); computer.readStorage(tfAdapter); // 使用Memory Stick System.out.println("\n=== 使用Memory Stick ==="); MemoryStick ms = new MemoryStick(); StorageDevice msAdapter = new MemoryStickAdapter(ms); computer.readStorage(msAdapter); } }
四、实际生产场景应用
4.1 场景:第三方支付适配器
系统需要集成多个支付渠道(支付宝、微信、银联),但它们的API各不相同。
/** * 目标接口:统一支付接口 */ public interface PaymentProcessor { /** * 支付 * @param orderId 订单号 * @param amount 金额 * @return 支付结果 */ PaymentResult pay(String orderId, double amount); /** * 退款 * @param orderId 订单号 * @param amount 金额 * @return 退款结果 */ PaymentResult refund(String orderId, double amount); /** * 查询订单 * @param orderId 订单号 * @return 订单状态 */ String queryOrder(String orderId); } /** * 支付结果 */ class PaymentResult { private boolean success; private String message; private String transactionId; public PaymentResult(boolean success, String message, String transactionId) { this.success = success; this.message = message; this.transactionId = transactionId; } // Getters public boolean isSuccess() { return success; } public String getMessage() { return message; } public String getTransactionId() { return transactionId; } @Override public String toString() { return "PaymentResult{" + "success=" + success + ", message='" + message + '\'' + ", transactionId='" + transactionId + '\'' + '}'; } }
被适配者:各第三方支付SDK
/** * 被适配者1:支付宝SDK(假设的API) */ public class AlipaySDK { public AlipayResponse trade(String outTradeNo, String amount) { System.out.println("[支付宝] 发起支付: 订单=" + outTradeNo + ", 金额=" + amount); // 模拟支付成功 AlipayResponse response = new AlipayResponse(); response.code = "10000"; response.msg = "Success"; response.tradeNo = "2025" + System.currentTimeMillis(); return response; } public AlipayResponse refundTrade(String outTradeNo, String refundAmount) { System.out.println("[支付宝] 发起退款: 订单=" + outTradeNo + ", 金额=" + refundAmount); AlipayResponse response = new AlipayResponse(); response.code = "10000"; response.msg = "Refund Success"; response.tradeNo = "R" + System.currentTimeMillis(); return response; } public AlipayResponse query(String outTradeNo) { System.out.println("[支付宝] 查询订单: " + outTradeNo); AlipayResponse response = new AlipayResponse(); response.code = "10000"; response.tradeStatus = "TRADE_SUCCESS"; return response; } // 支付宝响应对象 public static class AlipayResponse { public String code; public String msg; public String tradeNo; public String tradeStatus; } } /** * 被适配者2:微信支付SDK(假设的API) */ public class WeChatPaySDK { public WeChatPayResult unifiedOrder(String orderNo, int totalFee) { System.out.println("[微信支付] 统一下单: 订单=" + orderNo + ", 金额=" + totalFee + "分"); WeChatPayResult result = new WeChatPayResult(); result.returnCode = "SUCCESS"; result.resultCode = "SUCCESS"; result.transactionId = "WX" + System.currentTimeMillis(); return result; } public WeChatPayResult refundOrder(String orderNo, int refundFee) { System.out.println("[微信支付] 申请退款: 订单=" + orderNo + ", 金额=" + refundFee + "分"); WeChatPayResult result = new WeChatPayResult(); result.returnCode = "SUCCESS"; result.resultCode = "SUCCESS"; result.refundId = "R" + System.currentTimeMillis(); return result; } public WeChatPayResult orderQuery(String orderNo) { System.out.println("[微信支付] 查询订单: " + orderNo); WeChatPayResult result = new WeChatPayResult(); result.returnCode = "SUCCESS"; result.tradeState = "SUCCESS"; return result; } // 微信支付响应对象 public static class WeChatPayResult { public String returnCode; public String resultCode; public String transactionId; public String refundId; public String tradeState; } } /** * 被适配者3:银联支付SDK(假设的API) */ public class UnionPaySDK { public boolean consume(String orderId, String amt) { System.out.println("[银联支付] 消费交易: 订单=" + orderId + ", 金额=" + amt + "元"); return true; } public boolean refund(String orderId, String amt) { System.out.println("[银联支付] 退货交易: 订单=" + orderId + ", 金额=" + amt + "元"); return true; } public String queryTrans(String orderId) { System.out.println("[银联支付] 查询交易: " + orderId); return "00"; // 00表示成功 } }
适配器实现:
/** * 支付宝适配器 */ public class AlipayAdapter implements PaymentProcessor { private AlipaySDK alipaySDK; public AlipayAdapter() { this.alipaySDK = new AlipaySDK(); } @Override public PaymentResult pay(String orderId, double amount) { // 将amount转换为字符串格式 String amountStr = String.format("%.2f", amount); // 调用支付宝SDK AlipaySDK.AlipayResponse response = alipaySDK.trade(orderId, amountStr); // 转换响应格式 boolean success = "10000".equals(response.code); return new PaymentResult(success, response.msg, response.tradeNo); } @Override public PaymentResult refund(String orderId, double amount) { String amountStr = String.format("%.2f", amount); AlipaySDK.AlipayResponse response = alipaySDK.refundTrade(orderId, amountStr); boolean success = "10000".equals(response.code); return new PaymentResult(success, response.msg, response.tradeNo); } @Override public String queryOrder(String orderId) { AlipaySDK.AlipayResponse response = alipaySDK.query(orderId); return response.tradeStatus; } } /** * 微信支付适配器 */ public class WeChatPayAdapter implements PaymentProcessor { private WeChatPaySDK weChatPaySDK; public WeChatPayAdapter() { this.weChatPaySDK = new WeChatPaySDK(); } @Override public PaymentResult pay(String orderId, double amount) { // 微信支付使用分为单位 int totalFee = (int) (amount * 100); // 调用微信支付SDK WeChatPaySDK.WeChatPayResult result = weChatPaySDK.unifiedOrder(orderId, totalFee); // 转换响应格式 boolean success = "SUCCESS".equals(result.returnCode) && "SUCCESS".equals(result.resultCode); return new PaymentResult(success, "微信支付成功", result.transactionId); } @Override public PaymentResult refund(String orderId, double amount) { int refundFee = (int) (amount * 100); WeChatPaySDK.WeChatPayResult result = weChatPaySDK.refundOrder(orderId, refundFee); boolean success = "SUCCESS".equals(result.returnCode); return new PaymentResult(success, "退款成功", result.refundId); } @Override public String queryOrder(String orderId) { WeChatPaySDK.WeChatPayResult result = weChatPaySDK.orderQuery(orderId); return result.tradeState; } } /** * 银联支付适配器 */ public class UnionPayAdapter implements PaymentProcessor { private UnionPaySDK unionPaySDK; public UnionPayAdapter() { this.unionPaySDK = new UnionPaySDK(); } @Override public PaymentResult pay(String orderId, double amount) { String amountStr = String.valueOf(amount); boolean success = unionPaySDK.consume(orderId, amountStr); return new PaymentResult(success, success ? "支付成功" : "支付失败", orderId); } @Override public PaymentResult refund(String orderId, double amount) { String amountStr = String.valueOf(amount); boolean success = unionPaySDK.refund(orderId, amountStr); return new PaymentResult(success, success ? "退款成功" : "退款失败", orderId); } @Override public String queryOrder(String orderId) { String code = unionPaySDK.queryTrans(orderId); return "00".equals(code) ? "SUCCESS" : "FAIL"; } }
支付工厂和客户端:
/** * 支付处理器工厂 */ public class PaymentProcessorFactory { public static PaymentProcessor getProcessor(String paymentType) { switch (paymentType.toLowerCase()) { case "alipay": return new AlipayAdapter(); case "wechat": return new WeChatPayAdapter(); case "unionpay": return new UnionPayAdapter(); default: throw new IllegalArgumentException("不支持的支付类型: " + paymentType); } } } /** * 订单服务(客户端) */ public class OrderService { public void processPayment(String orderId, double amount, String paymentType) { System.out.println("\n========== 处理订单支付 =========="); System.out.println("订单号: " + orderId); System.out.println("金额: ¥" + amount); System.out.println("支付方式: " + paymentType); System.out.println("================================\n"); // 获取对应的支付处理器(适配器) PaymentProcessor processor = PaymentProcessorFactory.getProcessor(paymentType); // 统一调用支付接口 PaymentResult result = processor.pay(orderId, amount); System.out.println("\n支付结果: " + result); // 查询订单状态 String status = processor.queryOrder(orderId); System.out.println("订单状态: " + status + "\n"); } } /** * 测试类 */ public class PaymentAdapterDemo { public static void main(String[] args) { OrderService orderService = new OrderService(); // 使用支付宝支付 orderService.processPayment("ORDER001", 99.99, "alipay"); // 使用微信支付 orderService.processPayment("ORDER002", 199.50, "wechat"); // 使用银联支付 orderService.processPayment("ORDER003", 299.00, "unionpay"); } }
4.2 场景:日志框架适配器
系统需要支持多种日志框架(Log4j、Logback、JDK Logging),但又希望统一使用。
/** * 目标接口:统一日志接口 */ public interface Logger { void debug(String message); void info(String message); void warn(String message); void error(String message); } /** * 被适配者1:Log4j(假设的API) */ class Log4jLogger { private String name; public Log4jLogger(String name) { this.name = name; } public void log(int level, String msg) { String levelName = getLevelName(level); System.out.println("[Log4j] " + levelName + " - " + name + ": " + msg); } private String getLevelName(int level) { switch (level) { case 0: return "DEBUG"; case 1: return "INFO"; case 2: return "WARN"; case 3: return "ERROR"; default: return "UNKNOWN"; } } } /** * 被适配者2:JDK Logging */ class JdkLogger { private String name; public JdkLogger(String name) { this.name = name; } public void logp(String level, String sourceClass, String sourceMethod, String msg) { System.out.println("[JDK] " + level + " - " + name + "." + sourceMethod + ": " + msg); } } /** * Log4j适配器 */ public class Log4jAdapter implements Logger { private Log4jLogger log4jLogger; public Log4jAdapter(String name) { this.log4jLogger = new Log4jLogger(name); } @Override public void debug(String message) { log4jLogger.log(0, message); } @Override public void info(String message) { log4jLogger.log(1, message); } @Override public void warn(String message) { log4jLogger.log(2, message); } @Override public void error(String message) { log4jLogger.log(3, message); } } /** * JDK Logging适配器 */ public class JdkLoggerAdapter implements Logger { private JdkLogger jdkLogger; private String className; public JdkLoggerAdapter(String name) { this.jdkLogger = new JdkLogger(name); this.className = name; } @Override public void debug(String message) { jdkLogger.logp("FINE", className, "debug", message); } @Override public void info(String message) { jdkLogger.logp("INFO", className, "info", message); } @Override public void warn(String message) { jdkLogger.logp("WARNING", className, "warn", message); } @Override public void error(String message) { jdkLogger.logp("SEVERE", className, "error", message); } } /** * 日志工厂 */ public class LoggerFactory { private static String loggerType = "log4j"; // 可配置 public static Logger getLogger(String name) { if ("log4j".equals(loggerType)) { return new Log4jAdapter(name); } else if ("jdk".equals(loggerType)) { return new JdkLoggerAdapter(name); } throw new IllegalArgumentException("不支持的日志类型"); } public static void setLoggerType(String type) { loggerType = type; } } /** * 测试 */ class LoggerAdapterDemo { public static void main(String[] args) { // 使用Log4j System.out.println("=== 使用Log4j ==="); LoggerFactory.setLoggerType("log4j"); Logger logger1 = LoggerFactory.getLogger("com.example.Service"); logger1.info("应用启动"); logger1.warn("内存使用率较高"); // 切换到JDK Logging System.out.println("\n=== 切换到JDK Logging ==="); LoggerFactory.setLoggerType("jdk"); Logger logger2 = LoggerFactory.getLogger("com.example.Controller"); logger2.info("请求处理中"); logger2.error("请求处理失败"); } }
五、开源框架中的应用
5.1 Spring MVC的HandlerAdapter
Spring MVC使用适配器模式支持多种类型的Controller。
/** * Spring MVC的HandlerAdapter接口(简化版) * 不同类型的Handler需要不同的适配器来执行 */ public interface HandlerAdapter { /** * 判断是否支持该Handler */ boolean supports(Object handler); /** * 执行Handler */ void handle(Object handler, HttpServletRequest request, HttpServletResponse response) throws Exception; } /** * 简化的HttpServletRequest和Response */ class HttpServletRequest { private java.util.Map<String, String> parameters = new java.util.HashMap<>(); public String getParameter(String name) { return parameters.get(name); } public void setParameter(String name, String value) { parameters.put(name, value); } } class HttpServletResponse { private String content; public void setContent(String content) { this.content = content; } public String getContent() { return content; } } /** * 被适配者1:实现Controller接口的处理器 */ interface Controller { String handleRequest(HttpServletRequest request, HttpServletResponse response); } class UserController implements Controller { @Override public String handleRequest(HttpServletRequest request, HttpServletResponse response) { System.out.println("[Controller接口] 处理用户请求"); return "user-view"; } } /** * 被适配者2:使用@RequestMapping注解的处理器 */ class AnnotatedController { public String getUser(String id) { System.out.println("[注解Controller] 获取用户: " + id); return "user-detail"; } public String saveUser(String name) { System.out.println("[注解Controller] 保存用户: " + name); return "success"; } } /** * 适配器1:Controller接口适配器 */ class SimpleControllerHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { return handler instanceof Controller; } @Override public void handle(Object handler, HttpServletRequest request, HttpServletResponse response) throws Exception { Controller controller = (Controller) handler; String viewName = controller.handleRequest(request, response); response.setContent("View: " + viewName); } } /** * 适配器2:注解Controller适配器 */ class RequestMappingHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { return handler instanceof AnnotatedController; } @Override public void handle(Object handler, HttpServletRequest request, HttpServletResponse response) throws Exception { AnnotatedController controller = (AnnotatedController) handler; // 简化:根据请求路径调用不同方法 String uri = request.getParameter("uri"); String result; if ("/getUser".equals(uri)) { String id = request.getParameter("id"); result = controller.getUser(id); } else if ("/saveUser".equals(uri)) { String name = request.getParameter("name"); result = controller.saveUser(name); } else { result = "404"; } response.setContent("Result: " + result); } } /** * DispatcherServlet(简化版) */ class DispatcherServlet { private java.util.List<HandlerAdapter> handlerAdapters = new java.util.ArrayList<>(); public DispatcherServlet() { // 注册所有适配器 handlerAdapters.add(new SimpleControllerHandlerAdapter()); handlerAdapters.add(new RequestMappingHandlerAdapter()); } public void doDispatch(Object handler, HttpServletRequest request, HttpServletResponse response) throws Exception { // 找到支持该Handler的适配器 HandlerAdapter adapter = getHandlerAdapter(handler); if (adapter == null) { throw new Exception("没有找到支持的HandlerAdapter"); } // 使用适配器执行Handler adapter.handle(handler, request, response); } private HandlerAdapter getHandlerAdapter(Object handler) { for (HandlerAdapter adapter : handlerAdapters) { if (adapter.supports(handler)) { return adapter; } } return null; } } /** * 测试Spring MVC适配器 */ class SpringMVCAdapterDemo { public static void main(String[] args) throws Exception { DispatcherServlet servlet = new DispatcherServlet(); // 场景1:使用Controller接口 System.out.println("=== 场景1:Controller接口 ==="); Controller controller1 = new UserController(); HttpServletRequest request1 = new HttpServletRequest(); HttpServletResponse response1 = new HttpServletResponse(); servlet.doDispatch(controller1, request1, response1); System.out.println("响应: " + response1.getContent()); // 场景2:使用注解Controller System.out.println("\n=== 场景2:注解Controller ==="); AnnotatedController controller2 = new AnnotatedController(); HttpServletRequest request2 = new HttpServletRequest(); request2.setParameter("uri", "/getUser"); request2.setParameter("id", "123"); HttpServletResponse response2 = new HttpServletResponse(); servlet.doDispatch(controller2, request2, response2); System.out.println("响应: " + response2.getContent()); } }
5.2 Java I/O的InputStreamReader
InputStreamReader是字节流到字符流的适配器。
import java.io.*; /** * InputStreamReader的适配器模式 * * InputStream (字节流) → InputStreamReader → Reader (字符流) * (适配器) */ public class InputStreamReaderDemo { public static void main(String[] args) throws IOException { // InputStream只能读取字节 InputStream inputStream = new ByteArrayInputStream("Hello 世界".getBytes("UTF-8")); // InputStreamReader将字节流适配为字符流 Reader reader = new InputStreamReader(inputStream, "UTF-8"); // 现在可以按字符读取(自动处理字符编码) int c; while ((c = reader.read()) != -1) { System.out.print((char) c); } reader.close(); } } /** * 简化的InputStreamReader实现原理 */ class SimpleInputStreamReader extends Reader { private InputStream inputStream; private String charset; public SimpleInputStreamReader(InputStream inputStream, String charset) { this.inputStream = inputStream; this.charset = charset; } @Override public int read(char[] cbuf, int off, int len) throws IOException { // 读取字节 byte[] bytes = new byte[len]; int bytesRead = inputStream.read(bytes); if (bytesRead == -1) { return -1; } // 将字节转换为字符(适配过程) String str = new String(bytes, 0, bytesRead, charset); char[] chars = str.toCharArray(); // 复制到目标数组 System.arraycopy(chars, 0, cbuf, off, chars.length); return chars.length; } @Override public void close() throws IOException { inputStream.close(); } }
5.3 SLF4J日志门面
SLF4J通过适配器支持多种日志实现。
/** * SLF4J的适配器模式 * * SLF4J API (统一接口) * ↓ * ┌────┴────┬────────┬─────────┐ * │ │ │ │ * Log4j Logback JDK Log 其他... * Adapter Adapter Adapter * * 用户代码只依赖SLF4J接口,具体实现通过适配器桥接 */ public class SLF4JAdapterExample { // 简化的SLF4J Logger接口 interface Logger { void info(String msg); void error(String msg, Throwable t); } // 简化的LoggerFactory static class LoggerFactory { public static Logger getLogger(Class<?> clazz) { // 根据classpath中的实现选择适配器 // 这里简化为直接返回Log4j适配器 return new Log4jLoggerAdapter(clazz.getName()); } } // Log4j适配器实现 static class Log4jLoggerAdapter implements Logger { private String name; public Log4jLoggerAdapter(String name) { this.name = name; } @Override public void info(String msg) { // 适配到Log4j的API System.out.println("[Log4j-Adapter] INFO " + name + ": " + msg); } @Override public void error(String msg, Throwable t) { System.out.println("[Log4j-Adapter] ERROR " + name + ": " + msg); if (t != null) { t.printStackTrace(); } } } // 使用示例 public static void main(String[] args) { Logger logger = LoggerFactory.getLogger(SLF4JAdapterExample.class); logger.info("应用启动"); logger.error("发生错误", new Exception("测试异常")); } }
更多推荐

所有评论(0)