本文目录导读:

Java中的适配器模式(Adapter Pattern)主要用于解决接口不兼容的问题,让原本因接口不匹配而无法一起工作的类可以协同工作,在兼容旧接口的场景下,适配器模式非常实用。
核心概念
适配器模式就像一个电源转换插头:你的旧设备(旧接口)需要插入新插座(新接口),适配器就是中间的那个转换器。
兼容旧接口的典型场景
假设我们有一个旧的日志系统,它的接口是:
// 旧接口
public interface OldLogger {
void logMessage(String message);
}
旧系统中有个实现类:
public class OldLoggerImpl implements OldLogger {
@Override
public void logMessage(String message) {
System.out.println("旧的日志记录: " + message);
}
}
现在新系统要求使用新接口:
// 新接口
public interface NewLogger {
void log(String level, String message);
void debug(String message);
void info(String message);
void error(String message);
}
适配器模式实现(三种方式)
方式1:类适配器(通过继承)
// 适配器继承旧实现,实现新接口
public class LoggerAdapter extends OldLoggerImpl implements NewLogger {
@Override
public void log(String level, String message) {
// 将新接口调用转换为旧接口调用
logMessage("[" + level + "] " + message);
}
@Override
public void debug(String message) {
logMessage("[DEBUG] " + message);
}
@Override
public void info(String message) {
logMessage("[INFO] " + message);
}
@Override
public void error(String message) {
logMessage("[ERROR] " + message);
}
}
方式2:对象适配器(推荐,通过组合)
// 适配器持有旧对象的引用,实现新接口
public class LoggerAdapter implements NewLogger {
private OldLogger oldLogger; // 组合旧对象
public LoggerAdapter(OldLogger oldLogger) {
this.oldLogger = oldLogger;
}
@Override
public void log(String level, String message) {
oldLogger.logMessage("[" + level + "] " + message);
}
@Override
public void debug(String message) {
oldLogger.logMessage("[DEBUG] " + message);
}
@Override
public void info(String message) {
oldLogger.logMessage("[INFO] " + message);
}
@Override
public void error(String message) {
oldLogger.logMessage("[ERROR] " + message);
}
}
方式3:接口默认方法适配器(Java 8+)
如果旧接口是函数式接口或简单接口,可以用默认方法直接适配:
// 在新接口中添加静态工厂方法
public interface NewLogger {
void log(String level, String message);
void debug(String message);
void info(String message);
void error(String message);
// 将旧日志器适配为新日志器
static NewLogger adapt(OldLogger oldLogger) {
return new NewLogger() {
@Override
public void log(String level, String message) {
oldLogger.logMessage("[" + level + "] " + message);
}
@Override
public void debug(String message) {
oldLogger.logMessage("[DEBUG] " + message);
}
@Override
public void info(String message) {
oldLogger.logMessage("[INFO] " + message);
}
@Override
public void error(String message) {
oldLogger.logMessage("[ERROR] " + message);
}
};
}
}
实际使用示例
public class Application {
public static void main(String[] args) {
// 旧系统的日志器
OldLogger oldLogger = new OldLoggerImpl();
// 使用适配器
NewLogger logger = new LoggerAdapter(oldLogger);
// 新系统代码正常调用新接口
logger.info("系统启动成功");
logger.debug("加载配置文件...");
logger.error("数据库连接失败");
// 也可以直接使用静态工厂方法(方式3)
NewLogger logger2 = NewLogger.adapt(oldLogger);
logger2.info("通过工厂方法适配");
}
}
适配器模式的优缺点
优点
- 不用修改旧代码:完全兼容旧接口的实现
- 开闭原则:通过增加适配器类,而不是修改现有代码
- 解耦:新系统不直接依赖旧接口,只依赖适配器
- 重用性:可以适配多个不同的旧接口
缺点
- 增加复杂度:引入额外的适配器类
- 性能损耗:增加一层调用转发
- 可能掩盖设计问题:如果接口差异太大,可能说明设计需要重构
选择建议
| 适配器类型 | 适用场景 |
|---|---|
| 对象适配器(组合) | 大多数情况,更灵活,推荐使用 |
| 类适配器(继承) | 需要重写旧类的方法行为时 |
| 接口默认方法 | 适配逻辑简单,或需要批量适配时 |
最佳实践建议:
- 优先使用对象适配器(组合方式),因为它更灵活
- 如果旧接口实现有多个,考虑使用工厂模式创建适配器
- 适配器应该只做接口转换,不要增加额外业务逻辑
这样,你就可以在不修改旧代码的情况下,让旧接口无缝集成到新系统中了。