Java 设计模式西游篇 - 第八回:适配器模式通万国 女儿国语言无障碍

诗曰:

复制代码
异国语言不相通,接口不配难交流。
适配器模式来相助,万国语言无障碍。

📖 故事

话说师徒四人来到"女儿国",此地人说的都是"女儿语",唐僧听不懂。

唐僧愁道:"悟空,这女儿国的语言,为师一句也听不懂啊!"

悟空笑道:"师父莫急!徒儿找个翻译,用适配器模式,让女儿语和唐语互通!"

🐉 踩坑打怪:接口不配之劫

第一劫:接口不兼容
java 复制代码
// 女儿国翻译(女儿语接口)
public class NvErGuoTranslator {
    public void translateFromNvEr(String nvErText) {
        System.out.println("女儿语翻译:" + nvErText);
    }
    
    public String translateToNvEr(String tangText) {
        return "女儿语:" + tangText;
    }
}

// 唐僧(唐语接口)
public class TangSeng {
    public void speak(String tangText) {
        System.out.println("唐僧说:" + tangText);
    }
    
    public void listen(String tangText) {
        System.out.println("唐僧听:" + tangText);
    }
}

// 问题:接口不兼容!
// 女儿国国王想和唐僧对话,但接口对不上!

八戒抱怨: "猴哥!女儿国国王说女儿语,师父说唐语,咋交流?"

第二劫:强行适配
java 复制代码
// 笨办法:修改原有类
public class TangSeng {
    // 强行加女儿语方法
    public void speakNvEr(String nvErText) {
        // 翻译逻辑
        String tangText = translate(nvErText);
        speak(tangText);
    }
    
    private String translate(String nvErText) {
        // 翻译逻辑...
        return nvErText;
    }
}

悟空摇头: "呆子!这违反了'开闭原则'!不能改原来的类!"

⚔️ 适配器模式大法

方式一:类适配器(继承)
java 复制代码
// 目标接口:唐僧能理解的接口
public interface Translator {
    String translateToTang(String foreignText);
    String translateToForeign(String tangText);
}

// 被适配者:女儿国翻译
public class NvErGuoTranslator {
    public void translateFromNvEr(String nvErText) {
        System.out.println("女儿语翻译:" + nvErText);
    }
    
    public String translateToNvEr(String tangText) {
        return "女儿语:" + tangText;
    }
}

// 适配器:继承被适配者,实现目标接口
public class NvErAdapter extends NvErGuoTranslator implements Translator {
    @Override
    public String translateToTang(String foreignText) {
        // 调用父类方法,转换成目标格式
        System.out.println("【适配器】女儿语 → 唐语");
        return foreignText.replace("女儿语:", "");
    }
    
    @Override
    public String translateToForeign(String tangText) {
        // 调用父类方法
        return translateToNvEr(tangText);
    }
}
方式二:对象适配器(组合,推荐)
java 复制代码
// 适配器:持有被适配者的引用
public class NvErAdapter implements Translator {
    private NvErGuoTranslator nvErTranslator; // 组合
    
    public NvErAdapter(NvErGuoTranslator nvErTranslator) {
        this.nvErTranslator = nvErTranslator;
    }
    
    @Override
    public String translateToTang(String foreignText) {
        System.out.println("【适配器】女儿语 → 唐语");
        // 调用被适配者的方法
        nvErTranslator.translateFromNvEr(foreignText);
        return foreignText.replace("女儿语:", "");
    }
    
    @Override
    public String translateToForeign(String tangText) {
        System.out.println("【适配器】唐语 → 女儿语");
        return nvErTranslator.translateToNvEr(tangText);
    }
}
方式三:接口适配器(默认实现)
java 复制代码
// 接口有很多方法,但有些用不上
public interface MultiTranslator {
    String translateToTang(String text);
    String translateToNvEr(String text);
    String translateToWuLiang(String text); // 乌鸡国语
    String translateToBaoXiang(String text); // 宝象国语
    // ... 几十个国家的语言
}

// 抽象适配器:提供默认实现
public abstract class AbstractTranslator implements MultiTranslator {
    @Override
    public String translateToTang(String text) {
        return text; // 默认不翻译
    }
    
    @Override
    public String translateToNvEr(String text) {
        return text;
    }
    
    @Override
    public String translateToWuLiang(String text) {
        return text;
    }
    
    @Override
    public String translateToBaoXiang(String text) {
        return text;
    }
    // ... 其他方法默认实现
}

// 具体适配器:只实现需要的方法
public class NvErSimpleAdapter extends AbstractTranslator {
    @Override
    public String translateToNvEr(String tangText) {
        return "女儿语:" + tangText;
    }
    
    @Override
    public String translateToTang(String nvErText) {
        return nvErText.replace("女儿语:", "");
    }
    // 其他语言用默认实现(不翻译)
}
实战演练
java 复制代码
public class Main {
    public static void main(String[] args) {
        // 创建女儿国翻译
        NvErGuoTranslator nvErTranslator = new NvErGuoTranslator();
        
        // 创建适配器
        Translator adapter = new NvErAdapter(nvErTranslator);
        
        // 女儿国国王说话
        System.out.println("=== 女儿国国王说话 ===");
        String nvErText = "女儿语:御弟哥哥,留下来吧!";
        String tangText = adapter.translateToTang(nvErText);
        System.out.println("唐僧听到:" + tangText);
        
        // 唐僧回应
        System.out.println("\n=== 唐僧回应 ===");
        String tangReply = "贫僧要西天取经!";
        String nvErReply = adapter.translateToForeign(tangReply);
        System.out.println("女儿国国王听到:" + nvErReply);
    }
}

输出:

复制代码
=== 女儿国国王说话 ===
【适配器】女儿语 → 唐语
女儿语翻译:女儿语:御弟哥哥,留下来吧!
唐僧听到:御弟哥哥,留下来吧!

=== 唐僧回应 ===
【适配器】唐语 → 女儿语
女儿国国王听到:女儿语:贫僧要西天取经!

适配器模式的实战应用

Java 中的适配器
java 复制代码
// Java IO 中的适配器
// InputStreamReader 是 InputStream 到 Reader 的适配器
InputStream inputStream = System.in;
Reader reader = new InputStreamReader(inputStream); // 适配器

// Java 集合中的适配器
// Collections.enumeration() 把 Iterator 适配成 Enumeration
List<String> list = Arrays.asList("A", "B", "C");
Enumeration<String> enumeration = Collections.enumeration(list);
Spring 中的适配器
java 复制代码
// Spring MVC 中的 HandlerAdapter
// 把不同的 Controller 适配成统一的接口
public interface HandlerAdapter {
    boolean supports(Object handler);
    ModelAndView handle(HttpServletRequest request, 
                       HttpServletResponse response, 
                       Object handler) throws Exception;
}

🏆 战斗总结

唐僧赞叹: "悟空,这适配器模式果然精妙!不用改原来的类,就能让接口兼容!"

悟空得意: "师父,这还不止!适配器还能------"

优势 说明
复用旧代码 不用修改现有类
解决不兼容 让接口不同的类一起工作
符合开闭原则 对扩展开放,对修改封闭

本章要点

要点 说明
核心思想 将一个类的接口转换成客户期望的另一个接口
适用场景 接口不兼容、复用旧代码、第三方库集成
类型 类适配器、对象适配器、接口适配器
优点 复用旧代码、解决不兼容、符合开闭原则
缺点 增加复杂度、过度使用会增加系统混乱

下回预告

话说师徒继续西行,来到"万法归宗山"。法术太多太复杂,如何简化?且看外观模式!

欲知后事如何,且听第九回分解!


相关推荐
曲幽1 小时前
刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API
python·fastapi·web·translate·goldendict·libretranslate·stardict·pystardict
荣码1 小时前
用Streamlit给AI应用套个界面,10行代码出Web页面
java·python
兵慌码乱11 小时前
基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析
python·sqlite·信号与槽·pyqt5·数据库设计·桌面应用开发·事务处理
金銀銅鐵12 小时前
[Python] 体验用欧几里得算法计算最大公约数的过程
python·数学
FreakStudio16 小时前
W55MH32L-EVB 上手测评:硬件 TCP/IP 加持的以太网单片机,MicroPython 零门槛开发
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy·电子计算机
用户03321266636717 小时前
使用 Python 从零创建 Word 文档
python
Csvn1 天前
Python 两大经典坑点 —— 可变默认参数 & 闭包延迟绑定
后端·python
曲幽1 天前
别再用网页翻译看源码了!你的私人翻译神器LibreTranslate,部署避坑指南来了
python·docker·web·pot·translate·libretranslate·arogstranslate
用户556918817531 天前
#从脚本到独立程序:Python + Playwright 批量抓取的完整踩坑记录
python·自动化运维
槑有老呆1 天前
别再手搓 Prompt 了,那个叫"手动挡循环"
设计模式