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;
}

🏆 战斗总结

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

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

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

本章要点

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

下回预告

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

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


相关推荐
2301_8038756120 小时前
PHP 中处理会话数组时的类型错误解析与修复指南
jvm·数据库·python
m0_7436239220 小时前
c++如何批量修改文件后缀名_std--filesystem--replace_extension【实战】
jvm·数据库·python
我爱cope21 小时前
【从0开始学设计模式-10| 装饰模式】
java·开发语言·设计模式
2501_9142459321 小时前
CSS如何处理CSS变量作用域冲突_利用特定类名重写变量值
jvm·数据库·python
菜鸟学Python21 小时前
Python生态在悄悄改变:FastAPI全面反超,Django和Flask还行吗?
开发语言·python·django·flask·fastapi
<-->21 小时前
Megatron(全称 Megatron-LM,由 NVIDIA 开发)和 DeepSpeed(由 Microsoft 开发)
人工智能·pytorch·python·深度学习·transformer
测试19981 天前
2026最新软件测试面试八股文【附文档】
自动化测试·软件测试·python·测试工具·面试·职场和发展·测试用例
maqr_1101 天前
MySQL数据库迁移到云端如何保障安全_数据加密与SSL连接配置
jvm·数据库·python
u0109147601 天前
MySQL如何限制触发器递归调用的深度_防止触发器死循环方法
jvm·数据库·python
weixin_381288181 天前
MySQL中如何使用HEX函数转换十六进制_MySQL进制转换函数
jvm·数据库·python