代码世界的「万能转接头」:适配器模式的跨界艺术

代码世界的「万能转接头」:适配器模式的跨界艺术


一、当接口开始「鸡同鸭讲」

想象这样的场景:

你的Type-C接口的MacBook,遇上了古董级的VGA投影仪;

说东北话的张三,要跟讲粤语的李四讨论哲学;

新买的蓝牙耳机,遇到了只支持3.5mm接口的诺基亚...

这些魔幻现实主义的画面,正是适配器模式的用武之地!它就像代码世界的翻译官,让两个互相嫌弃的接口突然开始商业互吹。


二、跨界翻译的两种姿势(UML图)

1. 类适配器:继承式联姻
java 复制代码
   ┌─────────────┐       ┌─────────────┐
   │   Target    │       │  Adaptee    │
   ├─────────────┤       ├─────────────┤
   │ +request()  │       │ +oldRequest │
   └──────△──────┘      └──────┬──────┘
          │           ┌─────────┴─────────┐
          │           │                   │
   ┌─────────────┐     ▼
   │  Adapter    │
   ├─────────────┤
   │ +request()  │
   └─────────────┘
  • 通过多重继承实现(Java不支持,但可以用接口+继承模拟)
  • 像混血儿继承父母双方的基因
2. 对象适配器:组合式外交
java 复制代码
   ┌─────────────┐       ┌─────────────┐
   │   Target    │       │  Adaptee    │
   ├─────────────┤       ├─────────────┤
   │ +request()  │       │ +oldRequest │
   └──────△──────┘      └──────┬──────┘
          │                     │
          │           ┌─────────▼─────────┐
          └───────────┤     Adapter       │
                      ├───────────────────┤
                      │ -adaptee: Adaptee │
                      │ +request()        │
                      └───────────────────┘
  • 持有被适配者的引用(组合优于继承)
  • 像外交官带着翻译团队

三、代码翻译官的工作日常

场景:让方形钉子适配圆孔
java 复制代码
// 圆孔标准接口(Target)
interface RoundHole {
    boolean fits(RoundPeg peg);
}

// 方钉(被适配者)
class SquarePeg {
    private int width;
    
    public SquarePeg(int width) {
        this.width = width;
    }
    
    public int getWidth() {
        return width;
    }
}

// 方钉转圆孔适配器(对象适配器)
class SquarePegAdapter implements RoundHole {
    private SquarePeg peg;
    
    public SquarePegAdapter(SquarePeg peg) {
        this.peg = peg;
    }
    
    @Override
    public boolean fits(RoundPeg roundPeg) {
        // 将方钉对角线长度作为虚拟直径
        double virtualDiameter = peg.getWidth() * Math.sqrt(2);
        return virtualDiameter <= roundPeg.getDiameter();
    }
}

// 使用示例
SquarePeg squarePeg = new SquarePeg(5);
RoundHole hole = new SquarePegAdapter(squarePeg);
hole.fits(new RoundPeg(7)); // 自动转换判断

四、适配器三兄弟的职场PK

维度 类适配器 对象适配器
实现方式 继承 组合
灵活性 只能适配一个类 可以适配多个类
代码耦合 高(需要了解父类实现) 低(面向接口)
适用场景 需要重写部分行为 多数情况
现实类比 基因改造人 随身翻译器

选型指南

  • 需要覆盖被适配者方法 → 类适配器
  • 需要适配多个类 → 对象适配器
  • 不确定时 → 选对象适配器准没错

五、跨界合作的真实战场

  1. Java集合框架Collections.list()把老旧的Enumeration适配成Iterator
  2. Android开发BaseAdapter统一各种数据源的ListView显示
  3. Spring MVCHandlerAdapter处理不同类型的Controller
  4. 日志框架:SLF4J的桥接器适配Log4j/JUL/Logback
  5. 支付接口:统一支付宝/微信/银联的不同API

经典案例

java 复制代码
// 把老式Enumeration适配成现代Iterator
Enumeration<String> oldEnum = ...;
Iterator<String> newIterator = new EnumerationIteratorAdapter(oldEnum);

六、防翻车翻译指南

  1. 不要过度使用

    java 复制代码
    // 错误示范:适配器套适配器(俄罗斯套娃警告)
    new AdapterA(new AdapterB(new AdapterC(originObj)));
  2. 保持适配器轻量

    java 复制代码
    // 好的适配器应该像透明胶带
    class GoodAdapter implements Target {
        private Adaptee adaptee; // 仅持有必要引用
        // 简洁的转换逻辑...
    }
  3. 优先组合而非继承

    java 复制代码
    // 使用对象组合就像带翻译官
    // 而继承就像自己学会八国语言(累死)
  4. 注意性能损耗

    java 复制代码
    // 高频调用的场景要考虑转换开销
    // 必要时缓存转换结果
  5. 统一异常处理

    java 复制代码
    try {
        adaptedObject.operation();
    } catch (AdapteeException e) {
        throw new TargetException("翻译后的异常", e);
    }

七、跨界总结大会

适配器模式就像代码世界的瑞士军刀:

  • :用于接口不兼容的场景
  • :优先使用对象适配器
  • 不要:把适配器当万能胶滥用
  • 不要:忘记适配器带来的性能损耗

当你在Java标准库中看到Arrays.asList()时,请记住------这个把数组转List的神器,正是适配器模式的经典应用!

相关推荐
柑木3 分钟前
Rust-开发应用-如何实现单例
后端·rust
艾迪的技术之路3 分钟前
redisson使用lock导致死锁问题
java·后端·面试
struggleupwards5 分钟前
golang中defer的小坑
后端·go
hai99long6 分钟前
最终一致性分布式事务的解决方案
后端
独立开阀者_FwtCoder11 分钟前
国外最流行的 UI 组件库!适配 Vue、React、Angular!
前端·vue.js·后端
勇哥java实战分享14 分钟前
聊聊 RocketMQ 4.X 知识体系
后端
CodeSheep18 分钟前
小米汽车这薪资是认真的吗?
前端·后端·程序员
今天背单词了吗98021 分钟前
算法学习笔记:8.Bellman-Ford 算法——从原理到实战,涵盖 LeetCode 与考研 408 例题
java·开发语言·后端·算法·最短路径问题
天天摸鱼的java工程师24 分钟前
使用 Spring Boot 整合高德地图实现路线规划功能
java·后端